<!--
 * @页面名称:
 * @描述: 
 * @作者: 
 * @Date:
-->
<template>
  <div style="height: 100vh">
    <el-container id="container">
      <el-aside width="195px" class="aside">
        <div class="header">
          <el-icon><Document /></el-icon>
          &nbsp;图像预览
        </div>
        <div class="scroll" style="overflow: auto; height: calc(100% - 40px)">
          <ul style="margin: auto; padding: 0; margin-top: 5px">
            <draggable
              v-model="data.urls"
              chosenClass="chosen"
              forceFallback="true"
              animation="1000"
              item-key="id"
              @end="onEndDrag"
            >
              <template #item="{ element, index }">
                <li style="padding: 10px; padding-right: 25px">
                  <div style="display: inline; position: relative">
                    <span style="font-size: 12px; position: absolute; left: 0; width: 25px; text-align: right"
                      >{{ index + 1 }}.</span
                    >
                    <el-image
                      :class="{ imageListSelect: data.selectManyImages.indexOf(index) >= 0 }"
                      ref="imageList"
                      :src="element.src"
                      fit="contain"
                      alt="image.imageName"
                      imageIndex="{{index}}"
                      lazy
                      style="height: 150px; margin-left: 35px; width: 80%; border: 2px solid #dedede"
                      @click="!$event.ctrlKey && selectImage(element.src, index)"
                      @click.ctrl="selectManyImage(element.src, index)"
                    >
                    </el-image>
                  </div>
                </li>
              </template>
            </draggable>
          </ul>
        </div>
        <div class="total">总张数&nbsp;{{ data.urls.length }}</div>
      </el-aside>
      <el-container>
        <el-header height="70px">
          <div class="menuContainer">
            <ul>
              <li @click="data.isSetup = true" v-if="data.permissions.indexOf('scan-set-param') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/setup.png" />
                </div>
                <div class="menus">扫描设定</div>
              </li>
              <li @click="scan()" v-if="data.permissions.indexOf('scan') >= 0 && data.permissions.indexOf('oprate-right') < 0">
                <div class="iconContainer">
                  <img src="./images/icons/scan.png" />
                </div>
                <div class="menu">正常扫描</div>
              </li>
              <li @click="insertScan()" v-if="data.permissions.indexOf('scan') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/insertScan.png" />
                </div>
                <div class="menu">插入扫描</div>
              </li>
              <li @click="coverScan()" v-if="data.permissions.indexOf('scan') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/coverScan.png" />
                </div>
                <div class="menu">覆盖扫描</div>
              </li>
              <li @click="pageScan()" v-if="data.permissions.indexOf('scan-pagecover') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/pageCover.png" />
                </div>
                <div class="menu">封面扫描</div>
              </li>
              <li
                @click="data.isDownLoad = true"
                v-if="
                  data.permissions.indexOf('scan-major-pdf') >= 0 ||
                  data.permissions.indexOf('scan-major-ofd') >= 0 ||
                  data.permissions.indexOf('scan-major-zip') >= 0
                "
              >
                <div class="iconContainer">
                  <img src="./images/icons/export.png" />
                </div>
                <div class="menu">导出图像</div>
              </li>
              <li @click="mergeHorizontal(true)" v-if="data.permissions.indexOf('image-merge') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/merge-horizontal.png" />
                </div>
                <div class="menu">水平合并</div>
              </li>
              <li @click="mergeHorizontal(false)" v-if="data.permissions.indexOf('image-merge') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/merge-vertical.png" />
                </div>
                <div class="menu">垂直合并</div>
              </li>
              <li
                @click="upload()"
                v-if="data.permissions.indexOf('scan-upload-image') >= 0 && data.permissions.indexOf('oprate-right') < 0"
              >
                <div class="iconContainer">
                  <img src="./images/icons/upload.png" alt="一键上传" />
                </div>
                <div class="menu">一键上传</div>
              </li>
              <li @click="getLastBatch()" v-if="data.permissions.indexOf('scan-get-lastBatch') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/batch.png" />
                </div>
                <div class="menu">最后批次</div>
              </li>
              <!-- 无权限 -->
              <li @click="extractImage()" v-if="data.permissions.indexOf('ocr-extract-name') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/reco.png" />
                </div>
                <div class="menu">公文抽取</div>
              </li>
              <!-- 无权限 -->
              <li @click="extractImageByPid()" v-if="data.permissions.indexOf('ocr-extract-pid') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/pidExtract.png" />
                </div>
                <div class="menu">批次抽取</div>
              </li>
              <li @click="data.isSelectSortMode = true" v-if="data.permissions.indexOf('image-sort') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/sort.png" />
                </div>
                <div class="menu">骑订排序</div>
              </li>
              <li style="border-right: 1px solid #dfdfdf; height: 26px; margin-top: 10px"></li>
              <li @click="deleteImage()" v-if="data.permissions.indexOf('image-delete-name') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/delImage.png" />
                </div>
                <div class="menu">删除选定</div>
              </li>
              <li @click="localUpload()">
                <div class="iconContainer">
                  <img src="./images/icons/upload.png" alt="本地上传" />
                </div>
                <div class="menu">本地上传</div>
                <input ref="fileRef" type="file" style="display: none" multiple @change="fileSelected" />
              </li>
              <li @click="deleteAllImage()" v-if="data.permissions.indexOf('image-delete-all') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/delAll.png" />
                </div>
                <div class="menu">清空列表</div>
              </li>
              <!-- 无权限 -->
              <li @click="getAllOfd()" v-if="data.permissions.indexOf('custom-ofd-all') >= 0">
                <div class="iconContainer">
                  <img src="./images/icons/ofdList.png" />
                </div>
                <div class="menu">OFD列表</div>
              </li>
            </ul>
          </div>
        </el-header>
        <el-main id="main">
          <div
            style="height: 100%; float: left; position: relative"
            :class="data.permissions.indexOf('oprate-right') < 0 ? 'maincanvas_width' : 'maincanvas_width'"
            id="optCanvas"
          >
            <!--蒙板-->
            <div class="mask" v-if="data.isDisableOpt"></div>
            <div class="opt">
              <ul style="margin-left: -40px; line-height: 24px">
                <li @click="scaleMax">
                  <img src="./images/icons/amplify.png" title="放大" />
                </li>
                <li @click="scaleMin">
                  <img src="./images/icons/narrow.png" title="缩小" />
                </li>
                <li @click="ajustDimensions">
                  <img src="./images/icons/auto.png" title="自适应" />
                </li>
                <li @click="realDimensions">
                  <img src="./images/icons/real.png" title="实际大小" />
                </li>
                <li @click="addListenerToDiv">
                  <img src="./images/icons/drag.png" title="拖拽" />
                </li>
                <li @click="rotate(-90)" v-if="data.permissions.indexOf('image-rotate') >= 0">
                  <img src="./images/icons/left-roate.png" title="左旋90度" />
                </li>
                <li @click="rotate(90)" v-if="data.permissions.indexOf('image-rotate') >= 0">
                  <img src="./images/icons/right-roate.png" title="右旋90度" />
                </li>
                <li @click="rotate(180)" v-if="data.permissions.indexOf('image-rotate') >= 0">
                  <img src="./images/icons/roate.png" title="旋转180度" />
                </li>
                <li @click="innerErase"><img src="./images/icons/erase-inner.png" title="内擦除" /></li>
                <li @click="outerErase">
                  <img src="./images/icons/erase-outter.png" title="外擦除" />
                </li>
                <li @click="clip">
                  <img src="./images/icons/clip.png" title="裁剪" />
                </li>
                <li @click="rectification" id="rectification" v-if="data.permissions.indexOf('image-rotate') >= 0">
                  <img src="./images/icons/rectification.png" title="纠偏" />
                </li>
                <li @click="undo">
                  <img src="./images/icons/undo.png" title="撤销" v-if="data.undoStack.length > 0" />
                  <img src="./images/icons/undogray.png" title="撤销" v-if="data.undoStack.length <= 0" />
                </li>
                <li @click="redo">
                  <img src="./images/icons/redo.png" title="前进" v-if="data.redoStack.length > 0" />
                  <img src="./images/icons/redogray.png" title="前进" v-if="data.redoStack.length <= 0" />
                </li>
                <li @click="beforeSplitImage($event, true)" v-if="data.permissions.indexOf('image-split') >= 0">
                  <img src="./images/icons/split-horizontal.png" title="垂直拆分" />
                </li>
                <li @click="beforeSplitImage($event, false)" v-if="data.permissions.indexOf('image-split') >= 0">
                  <img src="./images/icons/split-vertical.png" title="水平拆分" />
                </li>
                <li @click="save" v-if="data.permissions.indexOf('image-save') >= 0">
                  <img src="./images/icons/save.png" title="保存" />
                </li>
              </ul>
            </div>
            <div
              class="image-container scroll"
              id="canvas-container"
              ref="canvasContainer"
              @contextmenu.prevent
              style="margin-left: 58px; margin: 0 auto; height: 100%"
            >
              <canvas id="imageCanvas" height="100%" width="100%"></canvas>
              <!--左侧按钮-->
              <div class="pageBtn" v-if="data.image != null">
                <el-button
                  class="info_button"
                  type="info"
                  :icon="ArrowLeft"
                  circle
                  @click="pre()"
                  style="float: left; margin-left: 10px"
                ></el-button>
              </div>
              <!--右侧按钮-->
              <div
                class="pageBtn"
                style="right: 20px"
                id="next_image"
                v-if="data.permissions.indexOf('oprate-right') < 0 && data.image != null"
              >
                <el-button
                  class="info_button"
                  type="info"
                  :icon="ArrowRight"
                  circle
                  @click="next()"
                  style="float: right"
                ></el-button>
              </div>
            </div>
          </div>
          <!--定制右侧按钮 -->
          <div
            class="right_panel"
            style="width: 150px; height: 100%; position: relative"
            v-if="data.permissions.indexOf('oprate-right') >= 0"
          >
            <div style="position: absolute; bottom: 100px; left: -20px">
              <ul>
                <li @click="upload()" style="cursor: pointer; margin-top: 15px">
                  <div class="iconContainer">
                    <img src="./images/icons/upload-right.png" alt="一键上传" />
                  </div>
                </li>
                <li @click="scan()" style="cursor: pointer">
                  <div class="iconContainer">
                    <img src="./images/icons/scan-right.png" />
                  </div>
                </li>
              </ul>
            </div>
          </div>
          <div class="right_panel" style="width: 800px; display: none; overflow: auto" id="extract_pane">
            <el-form :model="data.extract.doc" ref="doc">
              <el-form-item label-width="100px" label="发文单位" prop="sign_authority">
                <!--<el-input v-model="extract.doc.sign_authority" placeholder="发文单位"></el-input>-->
                <el-input type="textarea" rows="2" v-model="data.extract.doc.sign_authority" placeholder="发文单位"></el-input>
              </el-form-item>
              <el-form-item label-width="100px" label="发文字号" prop="issue_num">
                <!--<el-input v-model="extract.doc.issue_num" placeholder="发文字号"></el-input>-->
                <el-input type="textarea" rows="2" v-model="data.extract.doc.issue_num" placeholder="发文字号"></el-input>
              </el-form-item>
              <el-form-item label-width="100px" label="标题" prop="title">
                <!--<el-input v-model="extract.doc.title" placeholder="标题"></el-input>-->
                <el-input type="textarea" rows="2" v-model="data.extract.doc.title" placeholder="标题"></el-input>
              </el-form-item>
              <el-form-item label-width="100px" label="份号" prop="part_number">
                <!--<el-input v-model="extract.doc.part_number" placeholder="份号"></el-input>-->
                <el-input type="textarea" rows="2" v-model="data.extract.doc.part_number" placeholder="份号"></el-input>
              </el-form-item>
              <el-form-item label-width="100px" label="密级" prop="classification">
                <!--<el-input v-model="extract.doc.classification"  placeholder="密级和保密期限"></el-input>-->
                <el-input type="textarea" rows="2" v-model="data.extract.doc.classification" placeholder="密级"></el-input>
              </el-form-item>
              <el-form-item label-width="100px" label="保密期限" prop="classification">
                <!--<el-input v-model="extract.doc.classification_date"  placeholder="保密期限"></el-input>-->
                <el-input type="textarea" rows="2" v-model="data.extract.doc.classification_date" placeholder="保密期限">
                </el-input>
              </el-form-item>
              <el-form-item label-width="100px" label="紧急程度" prop="urgency">
                <!--<el-input v-model="extract.doc.urgency" placeholder="紧急程度"></el-input>-->
                <el-input type="textarea" rows="2" v-model="data.extract.doc.urgency" placeholder="紧急程度"></el-input>
              </el-form-item>

              <el-form-item label-width="100px" label="主送机关" prop="main_send">
                <!--<el-input v-model="extract.doc.main_send" placeholder="主送机关"></el-input>-->
                <el-input type="textarea" rows="2" v-model="data.extract.doc.main_send" placeholder="主送机关"></el-input>
              </el-form-item>
              <el-form-item label-width="100px" label="成文日期" prop="publish_date">
                <!--<el-input v-model="extract.doc.publish_date" placeholder="成文日期"></el-input>-->
                <el-input type="textarea" rows="2" v-model="data.extract.doc.publish_date" placeholder="成文日期"></el-input>
              </el-form-item>
              <!-- <el-form-item label-width="110px" label="抄送机关" prop="duplicate_send">
						<el-input v-model="extract.doc.duplicate_send" placeholder="抄送机关"></el-input>
					</el-form-item> -->
              <el-form-item label-width="100px" label="印发机关" prop="print_unit">
                <el-input type="textarea" rows="2" v-model="data.extract.doc.print_unit" placeholder="印发机关"></el-input>
                <!--<el-input v-model="extract.doc.print_unit" placeholder="印发机关"></el-input>-->
              </el-form-item>
              <el-form-item label-width="100px" label="正文" prop="main_text">
                <el-input type="textarea" rows="2" v-model="data.extract.doc.main_text" placeholder="正文"></el-input>
              </el-form-item>
              <el-form-item style="text-align: right">
                <el-button type="warning" @click="hideExtract()">隐藏</el-button>
                <el-button @click="resetForm">重置</el-button>
                <el-button type="primary" @click="uploadExtract()" v-if="data.permissions.indexOf('ocr-extract-uploadOfd') >= 0">
                  上传OFD</el-button
                >
                <el-button @click="beforeUpload()" v-if="data.permissions.indexOf('ocr-extract-uploadOfd') >= 0"
                  >上传地址</el-button
                >
                <el-button @click="saveExtractOfd" type="primary" v-if="data.permissions.indexOf('ocr-extract-downOfd') >= 0">
                  保存OFD</el-button
                >
              </el-form-item>
            </el-form>
          </div>
        </el-main>
        <el-footer style="border-top: 1px solid #ececec" v-if="data.rectificationDialog">
          <div style="display: flex; justify-content: center; align-items: center; height: 100%">
            <span>拖动旋转</span>
            <el-slider
              @change="sliderRotateChange"
              style="width: 600px; margin-left: 20px"
              v-model="data.repSliderValue"
              :min="-360"
              :max="360"
              :step="1"
              show-input
              size="small"
            ></el-slider>
          </div>
        </el-footer>
      </el-container>
    </el-container>
    <el-dialog title="扫描设定" v-model="data.isSetup" width="650px" :close-on-click-modal="false">
      <div class="messageBox">
        <el-form label-width="90px" :model="data.form" :rules="data.rules" ref="formRef" style="padding-left: 10px">
          <el-tabs :modelValuel="data.activeName">
            <el-tab-pane label="扫描参数" name="0">
              <el-form-item label="扫描模板">
                <el-select v-model="data.form.selectedModel" placeholder="模板" filterable @change="changeModel">
                  <el-option :key="model.id" :label="model.name" :value="model.id" v-for="model in data.modelList"></el-option>
                </el-select>
                <el-button style="margin-left: 5px" type="primary" @click="data.isManagerModel = true">管理模板</el-button>
              </el-form-item>
              <el-form-item label="设备" required>
                <el-select v-model="data.form.device" placeholder="请选择扫描仪" filterable>
                  <el-option :label="device" :value="device" v-for="device in data.devices" :key="device"> </el-option>
                </el-select>
                <el-button style="margin-left: 5px" type="primary" @click="getDevices()">获取</el-button>
              </el-form-item>
              <el-form-item label="自动进纸">
                <el-switch v-model="data.form.autofeeder"></el-switch>
              </el-form-item>
              <el-form-item label="模式">
                <el-radio-group v-model="data.form.pixel">
                  <el-radio :label="0">黑白</el-radio>
                  <el-radio :label="1">灰色</el-radio>
                  <el-radio :label="2">彩色</el-radio>
                </el-radio-group>
              </el-form-item>
              <el-row>
                <el-col :span="12">
                  <el-form-item label="去白页">
                    <el-radio-group v-model="data.form.white">
                      <el-radio :label="true">是</el-radio>
                      <el-radio :label="false">否</el-radio>
                    </el-radio-group>
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="单双面">
                    <el-radio-group v-model="data.form.single" :disabled="!data.form.autofeeder">
                      <el-radio :label="true">单面</el-radio>
                      <el-radio :label="false">双面</el-radio>
                    </el-radio-group>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row>
                <el-col :span="12">
                  <el-form-item label="格式">
                    <el-select v-model="data.form.format" placeholder="请选择格式">
                      <el-option label="jpg" value="jpg"></el-option>
                      <el-option label="png" value="png"></el-option>
                      <el-option label="bmp" value="bmp"></el-option>
                      <el-option label="tiff(不支持显示)" value="tiff"></el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="分辨率">
                    <el-select v-model="data.form.resolution" placeholder="请选择分辨率">
                      <el-option label="100" :value="100"></el-option>
                      <el-option label="150" :value="150"></el-option>
                      <el-option label="200" :value="200"></el-option>
                      <el-option label="300" :value="300"></el-option>
                      <el-option label="600" :value="600"></el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row>
                <el-col :span="9">
                  <el-form-item label="骑订排序">
                    <el-select v-model="data.form.sort" placeholder="请选择骑订排序方式" @change="changeSort">
                      <el-option v-for="item in data.sortOptions" :key="item.value" :label="item.label" :value="item.value">
                      </el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="15">
                  <i style="font-size: 12px; color: red; line-height: 3"
                    >* 针对A3拆分A4自动拆分排序,需开启图像分割，不可开启旋转</i
                  >
                </el-col>
              </el-row>
              <el-row>
                <el-col :span="12">
                  <el-form-item label="图像分隔" v-if="data.isWindows">
                    <el-select v-model="data.split" placeholder="请选择图像分隔">
                      <el-option
                        v-for="item in data.splitOptionsWindows"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                      ></el-option>
                    </el-select>
                  </el-form-item>
                  <el-form-item label="图像分隔" v-if="!data.isWindows">
                    <el-select v-model="data.splitLinux" placeholder="请选择图像分隔">
                      <el-option label="无" value="None"></el-option>
                      <el-option label="水平" value="Horizontal"></el-option>
                      <el-option label="垂直" value="Vertical"></el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="自动旋转" v-if="data.isWindows">
                    <el-select v-model="data.autoRotate" placeholder="是否开启自动旋转">
                      <el-option
                        v-for="(item, index) in data.autoRotateOptionsWindows"
                        :key="index"
                        :label="item.label"
                        :value="item.value"
                      ></el-option>
                    </el-select>
                  </el-form-item>
                  <el-form-item label="旋转" v-if="!data.isWindows">
                    <el-select v-model="data.autoRotateLinux" placeholder="请选择旋转角度">
                      <el-option
                        v-for="(item, index) in data.autoRotateOptionsLinux"
                        :key="index"
                        :label="item.label"
                        :value="item.value"
                      ></el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row>
                <el-col :span="12">
                  <el-form-item label="压缩格式" v-if="!data.isWindows && data.form.format == 'jpg'">
                    <el-select v-model="data.form.compress" placeholder="请选择压缩格式">
                      <el-option label="默认" value="0"></el-option>
                      <el-option label="100%" value="80"></el-option>
                      <el-option label="75%" value="100"></el-option>
                      <el-option label="50%" value="200"></el-option>
                      <el-option label="25%" value="400"></el-option>
                      <el-option label="10%" value="800"></el-option>
                    </el-select>
                  </el-form-item>
                  <el-form-item label="压缩格式" v-if="!data.isWindows && data.form.format == 'tiff'">
                    <el-select v-model="data.form.compress" placeholder="请选择压缩格式">
                      <el-option label="默认" value="0"></el-option>
                      <el-option label="PACKBITS compression" value="100"></el-option>
                      <el-option label="ZLIB compression" value="200"></el-option>
                      <el-option label="ADOBE DEFLATE compression" value="400"></el-option>
                      <el-option label="无" value="800"></el-option>
                      <el-option label="CCITT Group 3 fax encoding" value="1000"></el-option>
                      <el-option label="CCITT Group 4 fax encoding" value="2000"></el-option>
                      <el-option label="LZW compression" value="4000"></el-option>
                      <el-option label="JPEG compression" value="8000"></el-option>
                      <el-option label="LogLuv compression" value="10000"></el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="色彩校正" v-if="!data.isWindows">
                    <el-select v-model="data.form.mode" placeholder="请选择色彩校正">
                      <el-option label="无" :value="0"></el-option>
                      <el-option label="文本" :value="1"></el-option>
                      <el-option label="图片" :value="2"></el-option>
                      <el-option label="图文混合" :value="3"></el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-form-item label="裁切调整" v-if="!data.isWindows">
                <el-row>
                  <el-col :span="12">
                    <span style="margin-right: 5px">左:</span>
                    <el-input-number
                      v-model="data.form.cropAdjustLeft"
                      :precision="1"
                      :min="-10"
                      :max="10"
                      :step="0.1"
                      size="small"
                    ></el-input-number>
                  </el-col>
                  <el-col :span="12">
                    <span style="margin-right: 5px">上:</span>
                    <el-input-number
                      v-model="data.form.cropAdjustTop"
                      :precision="1"
                      :min="-10"
                      :max="10"
                      :step="0.1"
                      size="small"
                    ></el-input-number>
                  </el-col>
                  <el-col :span="12">
                    <span style="margin-right: 5px">右:</span>
                    <el-input-number
                      v-model="data.form.cropAdjustRight"
                      :precision="1"
                      :min="-10"
                      :max="10"
                      :step="0.1"
                      size="small"
                    ></el-input-number>
                  </el-col>
                  <el-col :span="12">
                    <span style="margin-right: 5px">下:</span>
                    <el-input-number
                      v-model="data.form.cropAdjustBottom"
                      :precision="1"
                      :min="-10"
                      :max="10"
                      :step="0.1"
                      size="small"
                    ></el-input-number>
                  </el-col>
                </el-row>
              </el-form-item>
              <el-row>
                <el-col :span="12">
                  <el-form-item label="加边框">
                    <el-radio-group v-model="data.form.cheek">
                      <el-radio v-for="(item, index) in data.cheeks" :key="index" :label="item.value">{{ item.label }} </el-radio>
                    </el-radio-group>
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="边框宽度">
                    <el-input-number
                      v-model="data.form.cheekWidth"
                      controls-position="right"
                      :precision="1"
                      :min="data.minCheek"
                      :max="data.maxCheek"
                      :step="0.1"
                      size="small"
                      :disabled="data.form.cheek == 0"
                    ></el-input-number>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row>
                <el-col :span="12">
                  <el-form-item label="旋转双面" v-if="!data.isWindows">
                    <el-radio-group v-model="data.flipSideRotationLinux" :disabled="data.autoRotateLinux == 'Auto Orientation'">
                      <el-radio v-for="(item, index) in data.flipSideRotationLinuxs" :key="index" :label="item.value">
                        {{ item.label }}
                      </el-radio>
                    </el-radio-group>
                  </el-form-item>
                  <el-form-item label="旋转双面" v-if="data.isWindows && !data.form.single">
                    <el-radio-group v-model="data.flipSideRotationWindows" :disabled="data.autoRotate == '1'">
                      <el-radio v-for="(item, index) in data.flipSideRotationWindowses" :key="index" :label="item.value">
                        {{ item.label }}
                      </el-radio>
                    </el-radio-group>
                  </el-form-item>
                </el-col>
              </el-row>
            </el-tab-pane>
            <el-tab-pane label="上传参数" name="1">
              <el-form-item label="模式">
                <el-radio-group v-model="data.form.upload.uploadMode">
                  <el-radio :label="0">HTTP</el-radio>
                  <el-radio :label="1">FTP</el-radio>
                  <el-radio :label="2">无</el-radio>
                </el-radio-group>
              </el-form-item>
              <div v-if="data.form.upload.uploadMode == '0'">
                <el-form-item label="地址">
                  <el-input v-model="data.form.upload.httpUrl" placeholder="请输入上传地址"></el-input>
                </el-form-item>
                <el-form-item label="文件名">
                  <el-input v-model="data.form.upload.fileName" placeholder="请输入接收文件参数名"></el-input>
                </el-form-item>
                <el-form-item label="上传方式">
                  <el-select v-model="data.form.upload.httpMethod" placeholder="请选择上传方式">
                    <el-option label="POST" value="POST"></el-option>
                    <el-option label="GET" value="GET"></el-option>
                    <el-option label="PUT" value="PUT"></el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="头(json)">
                  <el-input
                    type="textarea"
                    v-model="data.form.upload.header"
                    placeholder="请输入上传时需携带的header信息"
                  ></el-input>
                </el-form-item>
                <el-form-item label="参数(json)">
                  <el-input
                    type="textarea"
                    v-model="data.form.upload.param"
                    placeholder="请输入上传时需携带的参数信息"
                  ></el-input>
                </el-form-item>
              </div>
              <div v-if="data.form.upload.uploadMode == '1'">
                <el-form-item label="地址">
                  <el-input v-model="data.form.upload.ftpUrl" placeholder="请输入上传地址"></el-input>
                </el-form-item>
                <el-form-item label="端口">
                  <el-input v-model="data.form.upload.ftpPort" placeholder="请输入上传端口(默认21)"></el-input>
                </el-form-item>
                <el-form-item label="连接模式">
                  <el-radio-group v-model="data.form.upload.ftpMode">
                    <el-radio :label="1">主动</el-radio>
                    <el-radio :label="2">被动</el-radio>
                  </el-radio-group>
                </el-form-item>
                <el-form-item label="路径">
                  <el-input v-model="data.form.upload.ftpPath" placeholder="请输入ftp存放路径(默认/images)"></el-input>
                </el-form-item>
                <el-form-item label="用户名">
                  <el-input v-model="data.form.upload.ftpUser" placeholder="请输入ftp用户名"></el-input>
                </el-form-item>
                <el-form-item label="密码">
                  <el-input type="password" v-model="data.form.upload.ftpPassword" placeholder="请输入ftp密码"></el-input>
                </el-form-item>
              </div>
            </el-tab-pane>
            <el-tab-pane label="图像参数" name="2">
              <el-form-item label="图像路径">
                <el-cascader
                  v-model="data.form.scanSystem.imagePath"
                  :options="data.treeOptions"
                  :props="data.treeProps"
                  :placeholder="data.treePlaceHolder"
                  :show-all-levels="false"
                  separator="\"
                  clearable
                  style="width: 100%"
                >
                </el-cascader>
              </el-form-item>
              <el-form-item label="图像前缀">
                <el-input v-model="data.form.scanSystem.imagePreName" placeholder="图像名称前缀"></el-input>
              </el-form-item>
              <el-form-item label="+">
                <el-checkbox v-model="data.form.scanSystem.isDate">日期</el-checkbox>
                <el-select
                  placeholder="请选择"
                  v-model="data.form.scanSystem.datePattern"
                  :disabled="data.form.scanSystem.isDate == false"
                >
                  <el-option value="yyyyMMdd">yyyyMMdd </el-option>
                  <el-option value="yyyy-MM-dd">yyyy-MM-dd </el-option>
                  <el-option value="yyyy-M-d">yyyy-M-d </el-option>
                </el-select>
                <el-checkbox v-model="data.form.scanSystem.isTime" :disabled="data.form.scanSystem.isDate == false"
                  >时间</el-checkbox
                >
              </el-form-item>
              <el-form-item label="+">
                <el-radio-group v-model="data.form.scanSystem.random">
                  <el-radio :label="0">流水号</el-radio>
                  <el-radio :label="1">随机数</el-radio>
                </el-radio-group>
              </el-form-item>
              <el-form-item label="长度" v-if="data.form.scanSystem.random == 0">
                <el-select placeholder="请选择" v-model="data.form.scanSystem.randomLength">
                  <el-option value="4">4 </el-option>
                  <el-option value="5">5 </el-option>
                  <el-option value="6">6 </el-option>
                </el-select>
                <el-checkbox v-model="data.form.scanSystem.randomCover">同名覆盖</el-checkbox>
              </el-form-item>
            </el-tab-pane>
            <el-tab-pane label="系统设置" name="3">
              <el-form-item label="licence">
                <el-input
                  style="width: 50%"
                  v-model="data.form.scanSystem.licence"
                  placeholder="多个licence以分号分割"
                ></el-input>
                <el-button type="primary" style="margin-left: 5px" @click="approveLicence()">授权</el-button>
                <el-button type="warning" @click="clearLicence()">清空</el-button>
              </el-form-item>
              <el-form-item label="日志级别">
                <el-radio-group v-model="data.logLevel">
                  <el-radio label="DEBUG">DEBUG</el-radio>
                  <el-radio label="INFO">INFO</el-radio>
                  <el-radio label="WARN">WARN</el-radio>
                  <el-radio label="ERROR">ERROR</el-radio>
                </el-radio-group>
                <el-button type="primary" style="margin-left: 35px" @click="setLevel()">设置</el-button>
              </el-form-item>
              <el-form-item label="日志下载">
                <el-button size="small" type="primary" @click="downloadLogs()">下载日志</el-button>
              </el-form-item>
              <el-form-item label="OCR授权" v-if="data.permissions.indexOf('ocr-recognize') >= 0">
                <el-upload
                  ref="licenceUpload"
                  :action="data.uploadLicenceUrl"
                  :auto-upload="true"
                  :multiple="false"
                  name="licenceFile"
                  :show-file-list="false"
                  :before-upload="beforeUploadLicence"
                >
                  <el-button size="small" type="primary">点击上传</el-button>
                </el-upload>
              </el-form-item>
            </el-tab-pane>
            <el-tab-pane label="网络扫描" name="4">
              <el-form-item label="是否开启">
                <el-switch v-model="data.form.netWorkScanParam.isNetScan"></el-switch>
              </el-form-item>
              <el-form-item label="IP地址" v-if="data.form.netWorkScanParam.isNetScan">
                <el-input
                  v-model="data.form.netWorkScanParam.IpAddr"
                  placeholder="请输入IP地址"
                  :rules="[{ required: true, message: '请输入IP地址', trigger: 'blur' }]"
                ></el-input>
              </el-form-item>
            </el-tab-pane>
          </el-tabs>
        </el-form>
        <el-row justify="center" v-if="data.activeName != '4'">
          <el-button type="primary" @click="saveSetup()">保存</el-button>
          <el-button @click="data.isaddModel = true">添加到模板</el-button>
        </el-row>
      </div>
    </el-dialog>
    <el-dialog title="一键上传" v-model="data.isUploadAllImage" width="30%">
      <div class="messageBox">
        <el-form
          ref="uploadAllForm"
          :model="data.uploadAllForm"
          :rules="data.uploadAllRules"
          label-width="80px"
          style="padding-left: 10px"
        >
          <el-form-item label="模式">
            <el-radio-group v-model="data.uploadAllForm.uploadMode">
              <el-radio :label="0">HTTP</el-radio>
              <el-radio :label="1">FTP</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="上传格式">
            <el-radio-group v-model="data.uploadAllForm.format">
              <el-radio :label="0">ofd</el-radio>
              <el-radio :label="1">pdf</el-radio>
              <el-radio :label="2">zip</el-radio>
            </el-radio-group>
          </el-form-item>
          <div v-if="data.uploadAllForm.uploadMode == '0'">
            <el-form-item label="地址">
              <el-input v-model="data.uploadAllForm.httpUrl" placeholder="请输入上传地址"></el-input>
            </el-form-item>
            <el-form-item label="文件名">
              <el-input v-model="data.uploadAllForm.fileName" placeholder="请输入接收文件参数名"></el-input>
            </el-form-item>
            <el-form-item label="上传方式">
              <el-select v-model="data.uploadAllForm.httpMethod" placeholder="请选择上传方式">
                <el-option label="POST" value="POST"></el-option>
                <el-option label="GET" value="GET"></el-option>
                <el-option label="PUT" value="PUT"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="头(json)">
              <el-input
                type="textarea"
                v-model="data.uploadAllForm.header"
                placeholder="请输入上传时需携带的header信息"
              ></el-input>
            </el-form-item>
            <el-form-item label="参数(json)">
              <el-input type="textarea" v-model="data.uploadAllForm.param" placeholder="请输入上传时需携带的参数信息"></el-input>
            </el-form-item>
          </div>
          <div v-if="data.uploadAllForm.uploadMode == '1'">
            <el-form-item label="地址">
              <el-input v-model="data.uploadAllForm.ftpUrl" placeholder="请输入上传地址"></el-input>
            </el-form-item>
            <el-form-item label="端口">
              <el-input v-model="data.uploadAllForm.ftpPort" placeholder="请输入上传端口(默认21)"></el-input>
            </el-form-item>
            <el-form-item label="连接模式">
              <el-radio-group v-model="data.uploadAllForm.ftpMode">
                <el-radio :label="1">主动</el-radio>
                <el-radio :label="2">被动</el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="路径">
              <el-input v-model="data.uploadAllForm.ftpPath" placeholder="请输入ftp存放路径(默认/images)"></el-input>
            </el-form-item>
            <el-form-item label="用户名">
              <el-input v-model="data.uploadAllForm.ftpUser" placeholder="请输入ftp用户名"></el-input>
            </el-form-item>
            <el-form-item label="密码">
              <el-input type="password" v-model="data.uploadAllForm.ftpPassword" placeholder="请输入ftp密码"></el-input>
            </el-form-item>
          </div>
        </el-form>
        <el-row justify="center">
          <el-button type="primary" @click="uploadAllImage()">保存</el-button>
        </el-row>
      </div>
    </el-dialog>
    <el-dialog title="导出" v-model="data.isDownLoad" width="30%">
      <div class="messageBox">
        <el-form label-width="80px" style="padding-left: 10px">
          <el-form-item label="类型">
            <el-radio-group v-model="data.downLoadMode">
              <el-radio :label="0" v-if="data.permissions.indexOf('scan-major-ofd') >= 0">ofd</el-radio>
              <el-radio :label="1" v-if="data.permissions.indexOf('scan-major-pdf') >= 0">pdf</el-radio>
              <el-radio :label="2" v-if="data.permissions.indexOf('scan-major-zip') >= 0">zip</el-radio>
              <el-radio :label="3" v-if="data.permissions.indexOf('scan-major-docx') >= 0">docx</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="模式" v-if="data.downLoadMode == 0">
            <el-radio-group v-model="data.isDoubleOfd">
              <el-radio :label="0">单层</el-radio>
              <el-radio :label="1" v-if="data.permissions.indexOf('scan-major-ofd-double') >= 0">双层</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="模式" v-if="data.downLoadMode == 1">
            <el-radio-group v-model="data.isDoublePdf">
              <el-radio :label="0">单层</el-radio>
              <el-radio :label="1" v-if="data.permissions.indexOf('scan-major-pdf-double') >= 0">双层</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
        <el-row justify="center">
          <el-button type="primary" @click="downLoad()">确定</el-button>
        </el-row>
      </div>
    </el-dialog>
    <el-dialog title="骑订排序" v-model="data.isSelectSortMode" width="30%">
      <div class="messageBox">
        <el-form label-width="80px" style="padding-left: 10px">
          <el-form-item label="模式">
            <el-radio-group v-model="data.sortMode">
              <el-radio :label="0">首页先进</el-radio>
              <el-radio :label="1">尾页先进</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
        <el-row justify="center">
          <el-button type="primary" @click="sortImageHttp()">确定</el-button>
        </el-row>
      </div>
    </el-dialog>
    <el-dialog title="模板管理" v-model="data.isManagerModel" width="600px">
      <div class="messageBox">
        <!-- <el-button type="success" size="medium" icon="el-icon-plus" circle style="margin-bottom:10px" @click="isaddModel=true"></el-button> -->
        <el-table :data="data.modelList" border style="width: 100%">
          <el-table-column label="名称" width="350">
            <template #slot="scope">
              <span style="margin-left: 10px">{{ scope.row.name }}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template #slot="scope">
              <el-button
                size="small"
                @click="
                  data.modelEditId = scope.row.id;
                  data.isEditModel = true;
                  data.modelEditInputValue = scope.row.name;
                "
                v-if="scope.row.id != null"
                >编辑</el-button
              >
              <el-button
                size="small"
                type="danger"
                @click="modelManageDelete(scope.row.id)"
                v-if="!scope.row.present && scope.row.id != null"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
        <el-row justify="center" style="margin-top: 30px">
          <el-button type="primary" @click="data.isManagerModel = false">关闭</el-button>
        </el-row>
      </div>
    </el-dialog>
    <el-dialog title="添加模板" v-model="data.isaddModel" width="30%">
      <div class="messageBox">
        <el-form label-width="80px" style="padding-left: 10px">
          <el-form-item label="模板名称">
            <el-input v-model="data.modelAddInputValue" placeholder="请输入模板名称"></el-input>
          </el-form-item>
        </el-form>
        <el-row justify="center">
          <el-button type="primary" @click="modelManageAdd()">确定</el-button>
        </el-row>
      </div>
    </el-dialog>
    <el-dialog title="编辑模板" v-model="data.isEditModel" width="30%">
      <div class="messageBox">
        <el-form label-width="80px" style="padding-left: 10px">
          <el-form-item label="模板名称">
            <el-input v-model="data.modelEditInputValue" placeholder="请输入模板名称"></el-input>
          </el-form-item>
        </el-form>
        <el-row justify="center">
          <el-button type="primary" @click="editModel()">确定</el-button>
        </el-row>
      </div>
    </el-dialog>
    <el-dialog title="上传" v-model="data.extract.isBeforeUpload" width="550px">
      <div class="messageBox">
        <el-form label-width="80px" style="padding-left: 10px">
          <el-form-item label="uploadUrl">
            <el-input style="width: 80%" v-model="data.extract.uploadUrl" placeholder="上传地址"></el-input>
          </el-form-item>
        </el-form>
        <el-row justify="center">
          <el-button type="primary" @click="saveUploadUrl()">确定</el-button>
        </el-row>
      </div>
    </el-dialog>
    <!-- 授权 -->
    <el-dialog
      title="请先进行授权"
      v-model="data.preLicenceDialog"
      width="600px"
      max-height="600px"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
    >
      <div class="messageBox">
        <el-form label-width="80px" style="padding-left: 10px">
          <el-form-item label="licence">
            <el-input style="width: 50%" v-model="data.form.scanSystem.licence" placeholder="多个licence以分号分割"></el-input>
            <el-button type="primary" @click="approveLicence()">授权</el-button>
          </el-form-item>
        </el-form>
      </div>
    </el-dialog>
    <!-- 进度条 -->
    <div class="mask-defined" v-if="data.isProcess">
      <el-progress class="mask-defined-process" :stroke-width="20" :percentage="data.process" :text-inside="true"> </el-progress>
    </div>
    <ContextMenu ref="contextMenu" v-model:show="data.extract.contextMenuVisible" :options="data.extract.optionsComponent">
      <context-menu-item @click="recognizeRegion('sign_authority')" label="发文单位"></context-menu-item>
      <context-menu-item @click="recognizeRegion('issue_num')" label="发文字号"></context-menu-item>
      <context-menu-item @click="recognizeRegion('title')" label="标题"></context-menu-item>
      <context-menu-item @click="recognizeRegion('part_number')" label="份号"></context-menu-item>
      <context-menu-item @click="recognizeRegion('classification')" label="密级"></context-menu-item>
      <context-menu-item @click="recognizeRegion('classification_date')" label="保密期限"></context-menu-item>
      <context-menu-item @click="recognizeRegion('urgency')" label="紧急程度"></context-menu-item>
      <context-menu-item @click="recognizeRegion('main_send')" label="主送机关"></context-menu-item>
      <context-menu-item @click="recognizeRegion('publish_date')" label="成文日期"></context-menu-item>
      <context-menu-item @click="recognizeRegion('print_unit')" label="印发机关"></context-menu-item>
    </ContextMenu>

    <!-- <context-menu
      class="right-menu"
      ref="contextMenu"
      :options="data.extract.optionsComponent"
      v-model:show="data.extract.contextMenuVisible"
    >
      <p @click="recognizeRegion('sign_authority')">发文单位</p>
      <p @click="recognizeRegion('issue_num')">发文字号</p>
      <p @click="recognizeRegion('title')">标题</p>
      <p @click="recognizeRegion('part_number')">份号</p>
      <p @click="recognizeRegion('classification')">密级</p>
      <p @click="recognizeRegion('classification_date')">保密期限</p>
      <p @click="recognizeRegion('urgency')">紧急程度</p>
      <p @click="recognizeRegion('main_send')">主送机关</p>
      <p @click="recognizeRegion('publish_date')">成文日期</p>
      <p @click="recognizeRegion('print_unit')">印发机关</p>
    </context-menu> -->
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, PropType, toRefs } from "vue";
import draggable from "vuedraggable";
import { ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
import useCurrentInstance from "@/utils/useCurrentInstance";
import $ from "jquery";
import { fabric } from "fabric";
import { WebScan } from "./ts/WebScan";
import { utils } from "./ts/util";
import ProtocolCheck from "protocolcheck";
// import ContextMenu from "@imengyu/vue3-context-menu";
// import "@imengyu/vue3-context-menu/lib/vue3-context-menu.css";

export interface IProps {
  Path: string;
}
// props
const props = defineProps({
  images: {
    type: Array as PropType<IProps[] | any>,
    default: () => {
      return [];
    }
  }
});
const newImageArr = ref<any[]>([]);
props.images.forEach((item: any) => {
  const result = {
    src: item.Path,
    imageName: item.FileName
  };
  newImageArr.value.push(result);
});
console.log(newImageArr.value);

// const show = ref(true);
const { proxy } = useCurrentInstance();
// 各个组件实例
const canvasContainer = ref();
const contextMenu = ref();
const doc = ref();
const fileRef = ref();
// rules
const validateHttpSet = (_rule: any, value: string, callback: (arg0: Error) => void) => {
  if (scanForm.upload.uploadMode == "0" && value == "") {
    callback(new Error("请输入必填项"));
  }
};
const validateFtpSet = (_rule: any, value: string, callback: (arg0: Error) => void) => {
  if (scanForm.upload.uploadMode == "1" && value == "") {
    callback(new Error("请输入必填项"));
  }
};
// uploadAllRules
const validateUploadAllHttpSet = (_rule: any, value: string, callback: (arg0: Error) => void) => {
  if (uploadForm.uploadMode == "0" && value == "") {
    callback(new Error("请输入必填项"));
  }
};
const validateUploadAllFtpSet = (_rule: any, value: string, callback: (arg0: Error) => void) => {
  if (uploadForm.uploadMode == "1" && value == "") {
    callback(new Error("请输入必填项"));
  }
};
const networkScanParam = reactive({
  isNetScan: false,
  IpAddr: ""
});
const scanForm = reactive({
  device: "",
  autofeeder: true,
  pixel: 1,
  white: 0,
  single: false,
  format: "jpg",
  resolution: 100,
  isActual: true,
  isUI: false,
  cropAdjustTop: 0,
  cropAdjustLeft: 0,
  cropAdjustBottom: 0,
  cropAdjustRight: 0,
  compress: 0,
  mode: 0,
  //边框
  cheek: 0,
  cheekWidth: 0,
  upload: {
    uploadMode: 2 as number | string,
    httpUrl: "",
    fileName: "",
    httpMethod: "",
    header: "",
    param: "",
    ftpUrl: "",
    ftpPath: "/./images",
    ftpUser: "",
    ftpPassword: "",
    ftpPort: 21,
    ftpMode: 2
  },
  scanSystem: {
    licence: "",
    imagePath: "",
    imagePreName: "IMAGE",
    isDate: false,
    isTime: false,
    random: 1,
    randomLength: 4,
    randomCover: true,
    datePattern: "yyyyMMdd"
  },
  selectedModel: "",
  sort: "1",
  userId: "",
  netWorkScanParam: networkScanParam,
  isWindow: false,
  params: [] as any[]
});
const uploadForm = reactive({
  uploadMode: 0 as number | string,
  httpUrl: "",
  fileName: "",
  httpMethod: "",
  header: "",
  param: "",
  ftpUrl: "",
  ftpPath: "/./images",
  ftpUser: "",
  ftpPassword: "",
  ftpPort: 21,
  ftpMode: 2,
  format: 2
});
const extractDoc = reactive({
  part_number: "",
  classification: "",
  urgency: "",
  sign_authority: "",
  issue_num: "",
  title: "",
  main_send: "",
  publish_date: "",
  duplicate_send: "",
  print_unit: "",
  main_text: "",
  Issuer: "",
  classification_date: ""
});
const extractData = reactive({
  doc: extractDoc,
  contextMenuTarget: null,
  contextMenuVisible: false,
  optionsComponent: {
    zIndex: 3,
    minWidth: 230,
    x: 500,
    y: 200
  },
  drawing: false,
  Rect: null as any,
  selectStartPointer: {
    x: 0,
    y: 0
  },
  selectEndPointer: {
    x: 0,
    y: 0
  },
  uploadUrl: "",
  isBeforeUpload: false,
  isBeforeSaveOfd: false,
  ofdPath: "",
  ofdList: null,
  isOfdList: false
});
const data = reactive({
  urls: newImageArr.value,
  canvas: null as any,
  image: {
    width: 0,
    height: 0,
    angle: 0
  },
  WebScan: null as any,
  isSetup: false,
  isDoubleOfd: 0 as any,
  isSelectDoubleOfd: false,
  isSelectDoublePdf: false,
  isSelectSortMode: false,
  sortMode: 0,
  isDoublePdf: 0,
  isProcess: false,
  process: 0,
  form: scanForm,
  treeOptions: [],
  treePlaceHolder: "请选择图像路径",
  isDisableOpt: false,
  treeProps: {
    multiple: false,
    lazy: true,
    emitPath: false,
    checkStrictly: true,
    async lazyLoad(node: { level: number; value: any }, resolve: Function) {
      if (node.level === 0) {
        await data.WebScan.getFileExplore("", true, function (result: { code: number; data: any }) {
          if (result.code == 200) {
            data.treeOptions = result.data;
          }
        });
      } else {
        await data.WebScan.getFileExplore(node.value, true, function (result: { code: number; data: any }) {
          if (result.code == 200) {
            resolve(result.data);
          }
        });
      }
    },
    value: "id",
    label: "label",
    leaf: "isEnd"
  },
  devices: [] as any[],
  pid: "",
  imageName: "",
  loading: null as any,
  loadingPageShow: false,
  rectificationDialog: false,
  repSliderValue: 0,
  isWindows: false,
  assistLine: null as any,
  assistText: null,
  rules: {
    device: [{ required: true, message: "请选择扫描仪", trigger: "blur" }],
    "upload.httpUrl": [
      {
        validator: validateHttpSet,
        trigger: "blur"
      }
    ],
    "upload.httpMethod": [
      {
        validator: validateHttpSet,
        trigger: "blur"
      }
    ],
    "upload.fileName": [
      {
        validator: validateHttpSet,
        trigger: "blur"
      }
    ],
    "upload.ftpUrl": [
      {
        validator: validateFtpSet,
        trigger: "blur"
      }
    ],
    "upload.ftpPath": [
      {
        validator: validateFtpSet,
        trigger: "blur"
      }
    ]
  },
  activeName: "0",
  isInsertScan: false,
  selectImageObj: {
    index: -1
  } as any,
  selectManyImages: [] as any[],
  oprationImageObj: {} as any,
  redoStack: [] as any[],
  undoStack: [] as any[],
  startP: null as any,
  isUploadAllImage: false,
  uploadAllForm: uploadForm,
  uploadAllRules: {
    httpUrl: [
      {
        validator: validateUploadAllHttpSet,
        trigger: "blur"
      }
    ],
    httpMethod: [
      {
        validator: validateUploadAllHttpSet,
        trigger: "blur"
      }
    ],
    fileName: [
      {
        validator: validateUploadAllHttpSet,
        trigger: "blur"
      }
    ],
    ftpUrl: [
      {
        validator: validateUploadAllFtpSet,
        trigger: "blur"
      }
    ],
    ftpPath: [
      {
        validator: validateUploadAllFtpSet,
        trigger: "blur"
      }
    ]
  },
  permissions: [] as string[],
  isDownLoad: false,
  downLoadMode: 0,
  isPageCover: false,
  isReal: false,
  logLevel: "DEBUG",
  split: "0",
  autoRotate: "0",
  autoRotateLinux: "None",
  splitLinux: "",
  splitOptionsWindows: [
    {
      value: "0",
      label: "无"
    },
    {
      value: "1",
      label: "水平"
    },
    {
      value: "2",
      label: "垂直"
    }
  ],
  autoRotateOptionsWindows: [
    {
      value: "0",
      label: "关闭"
    },
    {
      value: "1",
      label: "打开"
    }
  ],
  autoRotateOptionsLinux: [
    {
      value: "None",
      label: "无"
    },
    {
      value: "90",
      label: "90度"
    },
    {
      value: "180",
      label: "180度"
    },
    {
      value: "270",
      label: "270度"
    },
    {
      value: "Auto Orientation",
      label: "自动旋转"
    }
  ],
  cheeks: [
    {
      value: 0,
      label: "无"
    },
    {
      value: 1,
      label: "白色"
    },
    {
      value: 2,
      label: "黑色"
    }
  ],
  sortOptions: [
    {
      value: "1",
      label: "无"
    },
    {
      value: "2",
      label: "首页先进"
    },
    {
      value: "3",
      label: "尾页先进"
    }
  ],
  flipSideRotationLinuxs: [
    {
      value: "Book",
      label: "左右翻页"
    },
    {
      value: "Fanfold",
      label: "上下翻页"
    }
  ],
  flipSideRotationWindowses: [
    {
      value: "0",
      label: "左右翻页"
    },
    {
      value: "1",
      label: "上下翻页"
    }
  ],
  canvasJson: null as null | string,
  minCheek: 0,
  maxCheek: 20,
  extract: extractData,
  modelList: [] as any[],
  isManagerModel: false,
  isaddModel: false,
  modelAddInputValue: "",
  isEditModel: false,
  modelEditInputValue: "",
  modelEditId: "",
  flipSideRotationLinux: "Book",
  flipSideRotationWindows: "0",
  uploadLicenceUrl: "",
  preLicenceDialog: false,
  isCoverScan: false
});
// 拉下框选择事件
const changeModel = (value: string) => {
  if (value == null || value == undefined || value == "") {
    return;
  }
  const loading = eleLoadding("加载参数");
  data.WebScan.loadModelById(value, function (result: any) {
    loading.close();
    if (result.code != 200) {
      eleMessage(result.msg, "warning");
      return;
    } else {
      if (result.data != null) {
        data.form = result.data;
        data.form.selectedModel = value;
        dealParams(result);
        data.isWindows = result.data.isWindow;
      }
    }
  });
};
// 获取设备列表
const getDevices = () => {
  const loading = eleLoadding();
  data.WebScan.getDevices(function (result: any) {
    loading.close();
    if (result.code != 200) {
      eleMessage(result.msg, "warning");
      return;
    } else {
      data.devices = result.data;
      //获取浏览器中的内存
      const localDevice = localStorage.getItem("webscan_device");
      if (localDevice != null && data.devices.includes(localDevice)) {
        data.form.device = localDevice;
      }
      if (data.devices != null && data.devices.length > 0) {
        if (data.form.device == null || data.form.device == undefined) {
          data.form.device = data.devices[0];
        }
      }
    }
  });
};
// 选择骑订排序
const changeSort = (val: string) => {
  if (val != null) {
    if (data.form.isWindow) {
      data.split = "1";
      data.autoRotate = "0";
    } else {
      data.splitLinux = "Horizontal";
      data.autoRotateLinux = "None";
    }
  }
};
// 清空licence
const clearLicence = () => {
  proxy.$confirm("清空授权将重启服务，造成短暂不用", "确认要清空授权吗？", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
    callback: function (value: string) {
      if (value == "confirm") {
        data.WebScan.clearLicence(function (data: any) {
          if (data.code == 200) {
            eleMessage("清空成功，请刷新。", "success");
          } else {
            eleMessage(data.msg, "warning");
          }
        });
      }
    }
  });
};
// 设置日志级别
const setLevel = () => {
  const loading = eleLoadding();
  data.WebScan.setLogLevel(data.logLevel, function (result: any) {
    loading.close();
    if (result.code == 200) {
      eleMessage("设置成功", "success");
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
// 下载日志
const downloadLogs = () => {
  data.WebScan.downloadLogs();
};
const beforeUploadLicence = () => {
  data.uploadLicenceUrl = data.WebScan.url + "/ocr/changeLicence";
};
// 保存扫描设定参数
const saveSetup = () => {
  data.form.params = [];
  if (data.isWindows) {
    if (data.split != null && data.split != undefined) {
      const split = {
        code: "9266",
        value: data.split,
        type: "4"
      };
      data.form.params.push(split);
    }
    if (data.autoRotate != null && data.autoRotate != undefined) {
      const autoRotate = {
        code: "1152",
        value: data.autoRotate,
        type: "6"
      };
      data.form.params.push(autoRotate);
    }
    if (data.flipSideRotationWindows != null && data.flipSideRotationWindows != undefined) {
      const flipSideRotation = {
        code: "1136",
        value: data.flipSideRotationWindows,
        type: "4"
      };
      data.form.params.push(flipSideRotation);
    }
  } else {
    if (data.splitLinux != null && data.splitLinux != undefined) {
      const split = {
        code: "split-image",
        value: data.splitLinux,
        type: ""
      };
      data.form.params.push(split);
    }
    if (data.autoRotateLinux != null && data.autoRotateLinux != undefined) {
      const autoRotate = {
        code: "rotate",
        value: data.autoRotateLinux,
        type: ""
      };
      data.form.params.push(autoRotate);
    }
    if (data.flipSideRotationLinux != null && data.flipSideRotationLinux != undefined) {
      const flipSideRotation = {
        code: "flip-side-rotation",
        value: data.flipSideRotationLinux,
        type: ""
      };
      data.form.params.push(flipSideRotation);
    }
  }
  data.WebScan.setParams(data.form, function (result: any) {
    if (result.code == 200) {
      eleMessage(result.msg, "success");
      data.isSetup = false;
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
// 下载
const downLoad = () => {
  data.isDownLoad = false;
  if (data.downLoadMode == 0) {
    exportOfd();
    return;
  } else if (data.downLoadMode == 1) {
    exportPdf();
    return;
  } else if (data.downLoadMode == 2) {
    downLoadZip();
    return;
  } else if (data.downLoadMode == 3) {
    downloadDocx();
    return;
  }
};
// 骑订排序
const sortImageHttp = () => {
  if (data.urls.length % 4 != 0) {
    eleMessage("图像数量不符合骑订排序规则，排序失败", "warning");
    return;
  }
  const loading = eleLoadding();
  data.WebScan.sortImage(data.sortMode, function (result: any) {
    loading.close();
    if (result.code == 200) {
      window.location.reload();
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
// 模板管理删除
const modelManageDelete = (id: string) => {
  proxy
    .$confirm("确定要删除模板吗?", "删除模板", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    })
    .then(() => {
      const loading = eleLoadding("删除模板...");
      data.WebScan.deleteModel(id, function (result: any) {
        loading.close();
        if (result.code == 200) {
          loadModels();
        } else {
          eleMessage(result.msg, "warning");
        }
      });
    });
};
// 扫描设定添加模板确认事件
const modelManageAdd = () => {
  if (data.modelAddInputValue == "" || data.modelAddInputValue == null) {
    eleMessage("请输入模板名称", "warning");
    return;
  }
  const modelValue = data.form;
  if (modelValue.params == null) {
    modelValue.params = [];
  }
  if (data.isWindows) {
    if (data.split != null && data.split != undefined) {
      const split = {
        code: "9266",
        value: data.split,
        type: "4"
      };
      data.form.params.push(split);
    }
    if (data.autoRotate != null && data.autoRotate != undefined) {
      const autoRotate = {
        code: "1152",
        value: data.autoRotate,
        type: "6"
      };
      data.form.params.push(autoRotate);
    }
    if (data.flipSideRotationWindows != null && data.flipSideRotationWindows != undefined) {
      const flipSideRotation = {
        code: "1136",
        value: data.flipSideRotationWindows,
        type: "4"
      };
      data.form.params.push(flipSideRotation);
    }
  } else {
    if (data.splitLinux != null && data.splitLinux != undefined) {
      const split = {
        code: "split-image",
        value: data.splitLinux,
        type: ""
      };
      data.form.params.push(split);
    }
    if (data.autoRotateLinux != null && data.autoRotateLinux != undefined) {
      const autoRotate = {
        code: "rotate",
        value: data.autoRotateLinux,
        type: ""
      };
      data.form.params.push(autoRotate);
    }
    if (data.flipSideRotationLinux != null && data.flipSideRotationLinux != undefined) {
      const flipSideRotation = {
        code: "flip-side-rotation",
        value: data.flipSideRotationLinux,
        type: ""
      };
      data.form.params.push(flipSideRotation);
    }
  }
  const loading = eleLoadding("添加模板...");
  const formStr = JSON.stringify(modelValue);
  data.WebScan.addModel(data.modelAddInputValue, formStr, function (result: any) {
    loading.close();
    if (result.code == 200) {
      data.isaddModel = false;
      data.isSetup = false;
      data.modelAddInputValue = "";
      loadModels();
      data.form.selectedModel = result.data;
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
// 编辑模板确认事件
const editModel = () => {
  if (data.modelEditId == null) {
    eleMessage("请选择模板", "warning");
    return;
  }
  if (data.modelEditInputValue == "") {
    eleMessage("请输入模板名称", "warning");
    return;
  }
  const loading = eleLoadding("修改模板...");
  data.WebScan.editModel(data.modelEditId, data.modelEditInputValue, function (result: any) {
    loading.close();
    if (result.code == 200) {
      data.isEditModel = false;
      data.modelEditId = "";
      data.modelEditInputValue = "";
      loadModels();
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
// 上传isInsertScan
const saveUploadUrl = () => {
  data.WebScan.setSystemValue("uploadUrl", data.extract.uploadUrl, function (result: any) {
    if (result.code != 200) {
      eleMessage(result.msg, "warning");
    } else {
      eleMessage("设置成功", "success");
      data.extract.isBeforeUpload = false;
    }
  });
};
// 授权确认事件
const approveLicence = () => {
  if (data.form.scanSystem.licence == "" || data.form.scanSystem.licence == null) {
    eleMessage("请输入授权码", "warning");
    return;
  }
  data.WebScan.licence = data.form.scanSystem.licence;
  data.WebScan.saveLicence(data.form.scanSystem.licence, function (result: any) {
    if (result.code != 200) {
      eleMessage(result.msg, "warning");
      return;
    }
    eleMessage("授权成功", "success");
    data.preLicenceDialog = false;
  });
};
// 正常扫描
const scan = () => {
  const result = data.WebScan.startScan(scanCallBack, null);
  if (result.code != 200) {
    eleMessage(result.msg, "warning");
    return;
  }
  data.isInsertScan = false;
  data.isCoverScan = false;
  data.loading = eleLoadding();
};
// 插入扫描
const insertScan = () => {
  if (data.selectImageObj == null || data.selectImageObj.image == null || data.selectImageObj.image == undefined) {
    eleMessage("请选择插入图像", "warning");
    return;
  }
  const imageName = data.selectImageObj.image.imageName;
  const scanData = {
    imageName: imageName,
    isInsert: true
  };
  const result = data.WebScan.startScan(scanCallBack, scanData);
  if (result.code != 200) {
    eleMessage(result.msg, "warning");
    return;
  }
  data.isInsertScan = true;
  data.isCoverScan = false;
  data.oprationImageObj = data.selectImageObj;
  data.loading = eleLoadding();
};
// 覆盖扫描
const coverScan = () => {
  if (data.selectImageObj == null || data.selectImageObj.image == null || data.selectImageObj.image == undefined) {
    eleMessage("请选择插入图像", "warning");
    return;
  }
  let imageName = data.selectImageObj.image.imageName;
  let scanData = {
    imageName: imageName,
    isCover: true
  };
  let result = data.WebScan.startScan(scanCallBack, scanData);
  if (result.code != 200) {
    eleMessage(result.msg, "warning");
    return;
  }
  data.isInsertScan = false;
  data.isCoverScan = true;
  data.oprationImageObj = data.selectImageObj;
  data.loading = eleLoadding();
};
// 封面扫描，仅生成两张图像。
const pageScan = () => {
  const scanData = {
    isPageCover: true
  };
  const result = data.WebScan.startScan(scanCallBack, scanData);
  if (result.code != 200) {
    eleMessage(result.msg, "warning");
    return;
  }
  data.isInsertScan = false;
  data.isCoverScan = false;
  data.isPageCover = true;
  data.loading = eleLoadding();
};
// 合并
const mergeHorizontal = (isHorizontal: boolean) => {
  if (data.selectManyImages == null || data.selectManyImages == undefined || data.selectManyImages.length <= 0) {
    eleMessage("请选择要合并的图像", "warning");
    return;
  }
  if (isHorizontal == null || isHorizontal == undefined) {
    isHorizontal = true;
  }
  const sortList = data.selectManyImages.sort();
  proxy.$confirm("此操作将合并文件，合并后不可恢复, 是否继续?", "合并", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
    callback: function (value: string) {
      if (value == "confirm") {
        const loading = eleLoadding();
        data.WebScan.merge(isHorizontal, sortList, function (result: any) {
          loading.close();
          if (result.code == 200) {
            const resultData = result.data;
            const image = {
              src: resultData.src,
              imageName: resultData.imageName
            };
            for (let i = 0; i < sortList.length; i++) {
              if (i != 0) {
                data.urls.splice(sortList[i], 1);
                data.selectManyImages.splice(i, 1);
              } else {
                data.urls.splice(sortList[i], 1, image);
                loadImage(data.urls[sortList[i]]);
              }
            }
          } else {
            eleMessage(result.msg, "warning");
          }
        });
      }
    }
  });
};
// 打开上传配置界面
const upload = () => {
  if (data.urls == null || data.urls.length <= 0) {
    eleMessage("图像列表为空，请刷新后尝试", "warning");
    return;
  }
  data.isUploadAllImage = true;
};
// 上传所有图像
const uploadAllImage = () => {
  data.isUploadAllImage = false;
  const loading = eleLoadding();
  data.WebScan.uploadImage(data.uploadAllForm, function (result: any) {
    loading.close();
    if (result.code == 200) {
      eleMessage("上传成功", "success");
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
// 获取最后批次的文件
const getLastBatch = () => {
  new utils().get({
    url: data.WebScan.url + "/getLastBatch",
    success: function (res: any) {
      if (res.code == 200) {
        if (res.data != null && res.data != data.pid) {
          sessionStorage.setItem("webscan_pid", res.data);
          window.location.reload();
        } else {
          eleMessage("当前批次已是最新批次", "warning");
          return;
        }
      } else {
        eleMessage(res.msg, "warning");
        return;
      }
    }
  });
};
// 公文抽取
const extractImage = () => {
  if (data.imageName == "" || data.imageName == null || data.imageName == undefined) {
    proxy.$alert("请选择图像", "警告！");
    return;
  }
  const loading = eleLoadding();
  data.WebScan.extractByImageName(data.imageName, function (data: any) {
    loading.close();
    if (data.code != 200) {
      proxy.$alert(data.msg, "警告！");
      return;
    }
    Object.keys(data.extract.doc).forEach(key => {
      data.extract.doc[key] = data.data[key];
    });
    addExtractEvent();
  });
};
// 添加公文抽取界面展示
const addExtractEvent = () => {
  //添加鼠标移动画框
  $("#extract_pane").css("display", "inline-block");
  $("#optCanvas").css("width", "calc(100% - 821px)");
  $("#next_image").css("right", "835px");
  clearDivListener();
  data.extract.contextMenuTarget = canvasContainer.value;
  contextMenu.value.bindEvents();
  data.canvas.on("mouse:down", function (e: any) {
    if (e.e.which != 1) {
      return;
    }
    //如果在rect的区域外重新绘画
    if (data.extract.Rect != null) {
      const rectPoints = data.extract.Rect.getBoundingRect();
      const start = data.canvas.getPointer(e);
      const zoom = data.canvas.getZoom();
      if (
        start.x > rectPoints.left / zoom - 15 &&
        start.x < rectPoints.left / zoom + rectPoints.width / zoom + 15 &&
        start.y > rectPoints.top / zoom - 15 &&
        start.y < rectPoints.top / zoom + rectPoints.height / zoom + 15
      ) {
        return;
      }
    }
    data.extract.selectStartPointer = data.canvas.getPointer(e);
    if (data.extract.Rect != null) {
      data.canvas.remove(data.extract.Rect);
      data.extract.Rect = null;
    }
    data.extract.drawing = true;
  });
  data.canvas.on("mouse:up", function (e: any) {
    if (data.extract.drawing == false) {
      return;
    }
    if (e.e.which != 1) {
      data.extract.drawing = false;
      return;
    }
    data.extract.selectEndPointer = data.canvas.getPointer(e);
    //计算开始结束点和范围
    let width = data.extract.selectEndPointer.x - data.extract.selectStartPointer.x;
    let height = data.extract.selectEndPointer.y - data.extract.selectStartPointer.y;
    if (width < 0) {
      width = -width;
    }
    if (height < 0) {
      height = -height;
    }
    if (width == height) {
      data.extract.drawing = false;
      return;
    }
    const startLeft = data.extract.selectStartPointer;
    if (data.extract.selectEndPointer.x < startLeft.x) {
      startLeft.x = data.extract.selectEndPointer.x;
    }
    if (data.extract.selectEndPointer.y < startLeft.y) {
      startLeft.y = data.extract.selectEndPointer.y;
    }
    //添加矩形区域
    data.extract.Rect = new fabric.Rect({
      hasBorders: true,
      hasControls: true,
      left: startLeft.x,
      top: startLeft.y,
      width: width,
      height: height,
      selectable: true,
      opacity: 0.2,
      centeredScaling: false
    }).setControlVisible("mtr", false);
    data.canvas.add(data.extract.Rect);
    data.extract.drawing = false;
  });
};
// 在批次前五张图像进行判别是否为红头文件
const extractImageByPid = () => {
  const loading = eleLoadding("公文提取中...");
  data.WebScan.extractImageByPid(function (result: any) {
    loading.close();
    if (result.code == 200) {
      const index = result.data["index"];
      //加载图像
      data.selectManyImages = [];
      data.selectManyImages.push(index);
      clearDivListener();
      data.canvas.clear();
      data.canvas.setZoom(1);
      // data.totalAngle = 0;
      data.canvas.discardActiveObject();
      if (data.urls[index] == undefined) {
        eleMessage("图像数据不同步，请刷新后尝试", "warning");
        return;
      }
      let src = data.urls[index].src;
      new fabric.Image.fromURL(
        src,
        function (image: any) {
          data.image = image;
          data.imageName = data.urls[index].imageName;
          data.canvas.add(image);
          data.canvas.renderAll();
          ajustDimensions();
          const dataUrl = data.canvas.toDatalessJSON();
          data.canvasJson = dataUrl;
          Object.keys(data.extract.doc).forEach((key: any) => {
            (data.extract.doc as any)[key] = result.data[key];
          });
          //保证图像加载完成以后添加鼠标事件
          addExtractEvent();
        },
        {
          selectable: false
        }
      );
      $(".canvas-container").css("border", "2px solid #e1e1e1");
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
// 删除选择的图像
const deleteImage = () => {
  if (data.selectManyImages == null || data.selectManyImages == undefined || data.selectManyImages.length <= 0) {
    eleMessage("请选择要删除的图像", "warning");
    return;
  }
  let sortList = data.selectManyImages.sort();
  proxy.$confirm("此操作将永久删除文件, 是否继续?", "删除", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
    callback: function (value: any) {
      if (value == "confirm") {
        let loading = eleLoadding();
        data.WebScan.deleteByIndexes(sortList, function (result: any) {
          loading.close();
          if (result.code == 200) {
            let index = sortList[sortList.length - 1];
            if (index == data.urls.length - 1) {
              index = 0;
            } else {
              index += 1;
            }
            let nextSelectImage = data.urls[index];
            for (let i = sortList.length - 1; i >= 0; i--) {
              data.urls.splice(sortList[i], 1);
            }
            let nextSelectIndex = data.urls.indexOf(nextSelectImage);
            if (data.urls.length > nextSelectIndex) {
              //选中下一个元素
              selectImage(data.urls[nextSelectIndex], nextSelectIndex);
            } else {
              clearDivListener();
              data.canvas.clear();
              data.canvas.setZoom(1);
              // that.totalAngle=0;
              data.canvas.discardActiveObject();
              $(".canvas-container").css("border", "none");
            }
            eleMessage("删除成功", "success");
          } else {
            eleMessage(result.msg, "warning");
          }
        });
      }
    }
  });
};
// 删除批次下的所有图像
const deleteAllImage = () => {
  proxy.$confirm("此操作将永久清除该批次文件, 是否继续?", "清空列表", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
    callback: function (value: any) {
      if (value == "confirm") {
        const loading = eleLoadding();
        const result = data.WebScan.deleteAllImage(function (res: any) {
          loading.close();
          if (res.code == 200) {
            data.urls = [];
            eleMessage("清空成功", "success");
            // window.location.reload();
          } else {
            eleMessage(res.msg, "warning");
          }
        });
      }
    }
  });
};
// 获取所有ofd
const getAllOfd = () => {
  data.WebScan.getTodayOfd(function (result: any) {
    if (result.code != 200) {
      proxy.$alert(result.msg, "warning");
    } else {
      const path = result.data.parentPath;
      data.extract.ofdPath = path;
      data.extract.ofdList = result.data.files;
      data.extract.isOfdList = true;
    }
  });
};
// 放大
const scaleMax = ($event: any) => {
  addOptActive($event);
  clearDivListener();
  if (data.image == null) {
    proxy.$message.warning("请选择图像进行操作");
    return;
  }
  const offset = 0.1;
  let scale = data.canvas.getZoom();
  scale += offset;
  const canvasWidth = data.image.width * scale;
  const canvasHeight = data.image.height * scale;
  const angle = Math.trunc(data.image.angle);
  const oldEven = (angle / 90) % 2;
  if (oldEven != 0 && angle % 90 == 0) {
    data.canvas.setDimensions({
      width: canvasHeight,
      height: canvasWidth
    });
  } else {
    data.canvas.setDimensions({
      width: canvasWidth,
      height: canvasHeight
    });
  }
  data.canvas.setZoom(scale);
};
// 缩小
const scaleMin = ($event: any) => {
  addOptActive($event);
  clearDivListener();
  if (data.image == null) {
    proxy.$message.warning("请选择图像进行操作");
    return;
  }
  const offset = 0.1;
  let scale = data.canvas.getZoom();
  scale -= offset;
  if (scale < 0.1) {
    scale = 0.1;
  }
  const canvasWidth = data.image.width * scale;
  const canvasHeight = data.image.height * scale;
  const angle = Math.trunc(data.image.angle);
  const oldEven = (angle / 90) % 2;
  if (oldEven != 0 && angle % 90 == 0) {
    data.canvas.setDimensions({
      width: canvasHeight,
      height: canvasWidth
    });
  } else {
    data.canvas.setDimensions({
      width: canvasWidth,
      height: canvasHeight
    });
  }
  data.canvas.setZoom(scale);
};
// 为canvas外层添加鼠标按下和监听
const addListenerToDiv = ($event: any) => {
  addOptActive($event);
  clearDivListener();
  let startX = 0;
  let startY = 0;
  data.canvas.defaultCursor = "pointer";
  data.canvas.hoverCursor = "pointer";
  $("#canvas-container").bind("mousedown", function (e: any) {
    startX = e.offsetX;
    startY = e.offsetY;
    data.canvas.selection = false;
    $("#canvas-container").bind("mousemove", function (e: any) {
      const endX = e.offsetX;
      const endY = e.offsetY;
      const offsetX = startX - endX;
      const offsetY = startY - endY;
      //获取现在X的滚动长度
      const scrollY = document.getElementById("canvas-container")?.scrollTop as any;
      //获取当前Y的滚动长度
      const scrollX = document.getElementById("canvas-container")?.scrollLeft as any;
      document.getElementById("canvas-container")?.scrollTo(scrollX + offsetX, offsetY + scrollY);
    });
  });
  $("#canvas-container").bind("mouseup", function (e: any) {
    $("#canvas-container").unbind("mousemove");
  });
};
// 旋转
const rotate = (rotate: number, $event?: any) => {
  if ($event != undefined) {
    addOptActive($event);
  }
  clearDivListener();
  addUndoStack();
  rotateAngle(rotate);
};
const addUndoStack = () => {
  let canvasJSON = data.canvas.toJSON(["selection", "hasControls", "selectable"]);
  canvasJSON["zoom"] = data.canvas.getZoom();
  canvasJSON["angle"] = Math.trunc(data.image.angle);
  data.undoStack.push(canvasJSON);
};
// 旋转图像
const rotateAngle = (rotate: number) => {
  const zoom = data.canvas.getZoom();
  const group = new fabric.ActiveSelection(data.canvas.getObjects(), {
    selectable: false,
    hasBorders: false,
    hasControls: false,
    centeredRotation: true,
    originX: "center",
    originY: "center"
  });
  // this.totalAngle+=rotate;
  group.rotate(rotate);
  let orignalWidth = data.image.width;
  let orignalHeight = data.image.height;
  let angle = Math.trunc(data.image.angle);
  angle += rotate;
  const oldEven = (angle / 90) % 2;
  if (oldEven != 0 && angle % 90 == 0) {
    orignalWidth = data.image.height;
    orignalHeight = data.image.width;
  }
  group.set({
    left: orignalWidth / 2,
    top: orignalHeight / 2
  });
  data.canvas.setDimensions({
    width: orignalWidth * zoom,
    height: orignalHeight * zoom
  });
  data.canvas.setBackgroundColor("#ffffff");
  data.canvas.renderAll.bind(data.canvas);
  group.destroy();
};
// 内擦除
const innerErase = ($event: any) => {
  addOptActive($event);
  clearDivListener();
  data.canvas.hoverCursor = "crosshair";
  data.canvas.defaultCursor = "crosshair";
  data.canvas.selection = true;
  data.canvas.on("mouse:down", function (e: any) {
    data.startP = data.canvas.getPointer(e);
  });
  data.canvas.on("mouse:up", function (e: any) {
    const endPointer = data.canvas.getPointer(e);
    if (endPointer.x == data.startP.x && endPointer.y == data.startP.y) {
      return;
    }
    //计算开始结束点和范围
    let width = endPointer.x - data.startP.x;
    let height = endPointer.y - data.startP.y;
    if (width < 0) {
      width = -width;
    }
    if (height < 0) {
      height = -height;
    }
    const startLeft = data.startP;
    if (endPointer.x < startLeft.x) {
      startLeft.x = endPointer.x;
    }
    if (endPointer.y < startLeft.y) {
      startLeft.y = endPointer.y;
    }
    //添加矩形区域
    const rect = new fabric.Rect({
      fill: "rgb(255,255,255)",
      hasBorders: false,
      hasControls: false,
      left: startLeft.x,
      top: startLeft.y,
      width: width,
      height: height,
      preserveObjectStacking: true,
      selectable: false
    });
    addUndoStack();
    data.canvas.add(rect);
  });
};
// 外擦除
const outerErase = ($event: any) => {
  addOptActive($event);
  clearDivListener();
  // this.canvas.discardActiveObject();
  data.canvas.hoverCursor = "crosshair";
  data.canvas.selection = true;
  data.canvas.on("mouse:down", function (e: any) {
    data.startP = data.canvas.getPointer(e);
  });
  data.canvas.on("mouse:up", function (e: any) {
    const endPointer = data.canvas.getPointer(e);
    if (endPointer.x == data.startP.x && endPointer.y == data.startP.y) {
      return;
    }
    //计算开始结束点和范围
    let width = endPointer.x - data.startP.x;
    width = width < 0 ? -width : width;
    let height = endPointer.y - data.startP.y;
    height = height < 0 ? -height : height;

    const startP = { x: data.startP.x, y: data.startP.y };
    const endP = { x: endPointer.x, y: endPointer.y };
    if (endPointer.x < data.startP.x) {
      startP.x = endPointer.x;
      endP.x = data.startP.x;
    }
    if (endPointer.y < data.startP.y) {
      startP.y = endPointer.y;
      endP.y = data.startP.y;
    }
    //区域外的地方设置为透明
    const rectTop = new fabric.Rect({
      fill: "rgb(255,255,255)",
      hasBorders: false,
      hasControls: false,
      left: 0,
      top: 0,
      width: data.image.width,
      height: startP.y,
      selectable: false
    });

    const rectLeft = new fabric.Rect({
      fill: "rgb(255,255,255)",
      hasBorders: false,
      hasControls: false,
      left: 0,
      top: 0,
      width: startP.x,
      height: data.image.height,
      selectable: false
    });

    const rectBottom = new fabric.Rect({
      fill: "rgb(255,255,255)",
      hasBorders: false,
      hasControls: false,
      left: 0,
      top: endP.y,
      width: data.image.width,
      height: data.image.height - endP.y,
      selectable: false
    });
    const rectRight = new fabric.Rect({
      fill: "rgb(255,255,255)",
      hasBorders: false,
      hasControls: false,
      left: endP.x,
      top: 0,
      width: data.image.width - endP.x,
      height: data.image.height,
      selectable: false
    });
    addUndoStack();
    data.canvas.add(rectBottom);
    data.canvas.add(rectLeft);
    data.canvas.add(rectTop);
    data.canvas.add(rectRight);
  });
};
// 裁剪
const clip = ($event: any) => {
  addOptActive($event);
  clearDivListener();
  data.canvas.hoverCursor = "crosshair";
  data.canvas.defaultCursor = "crosshair";
  data.canvas.selection = true;
  data.canvas.on("mouse:down", function (e: any) {
    data.startP = data.canvas.getPointer(e);
  });
  data.canvas.on("mouse:up", function (e: any) {
    const endPointer = data.canvas.getPointer(e);
    if (endPointer.x == data.startP.x && endPointer.y == data.startP.y) {
      return;
    }
    //计算开始结束点和范围
    let width = endPointer.x - data.startP.x;
    let height = endPointer.y - data.startP.y;
    if (width < 0) {
      width = -width;
    }
    if (height < 0) {
      height = -height;
    }
    let startLeft = data.startP;
    if (endPointer.x < startLeft.x) {
      startLeft.x = endPointer.x;
    }
    if (endPointer.y < startLeft.y) {
      startLeft.y = endPointer.y;
    }
    let zoom = data.canvas.getZoom();
    addUndoStack();
    zoom = 1 / zoom;
    realDimensions();
    //canvas恢复原始尺寸，然后裁切
    const dataUrl = data.canvas.toDataURL({
      format: "jpeg",
      left: startLeft.x,
      top: startLeft.y,
      width: width,
      height: height,
      quality: 1,
      multiplier: zoom
    });
    new fabric.Image.fromURL(
      dataUrl,
      function (image: any) {
        data.image = image;
        data.canvas.clear();
        data.canvas.add(image);
        data.canvas.renderAll();
        ajustDimensions();
      },
      {
        selectable: false
      }
    );
  });
};
// 纠偏
const rectification = ($event: any) => {
  if ($event != undefined) {
    addOptActive($event);
  }
  clearDivListener();
  data.rectificationDialog = true;
  data.repSliderValue = Math.trunc(data.image.angle);
};
// 撤销
const undo = ($event: any) => {
  if (data.undoStack.length <= 0) {
    return false;
  }
  addOptActive($event);
  clearDivListener();
  const undo = data.undoStack.pop();
  const zoom = undo["zoom"] || data.canvas.getZoom();
  if (undo == undefined) {
    return false;
  }
  //确定图像
  const redo = data.canvas.toJSON(["selection", "hasControls", "selectable"]);
  redo["zoom"] = data.canvas.getZoom();
  redo["angle"] = Math.trunc(data.image.angle);
  data.redoStack.push(redo);
  data.canvas.loadFromJSON(undo, data.canvas.renderAll.bind(data.canvas));
  data.canvas.renderAll();
  const objects = undo.objects;
  let image: any = null;
  if (objects != null && objects.length > 0) {
    for (let i = 0; i < objects.length; i++) {
      const type = objects[i].type;
      if (type == "image") {
        image = objects[i];
        data.image = image;
        break;
      }
    }
  }
  if (image != null) {
    const angle = undo["angle"] || Math.trunc(image.angle);
    let orignalWidth = image.width;
    let orignalHeight = image.height;
    const oldEven = (angle / 90) % 2;
    if (oldEven != 0 && angle % 90 == 0) {
      orignalWidth = data.image.height;
      orignalHeight = data.image.width;
    }
    data.canvas.setDimensions({
      width: orignalWidth * zoom,
      height: orignalHeight * zoom
    });
    data.canvas.setZoom(zoom);
    data.canvas.setBackgroundColor("#ffffff");
    data.canvas.renderAll.bind(data.canvas);
  }
  data.canvas.renderAll();
};
// 重做
const redo = ($event: any) => {
  if (data.redoStack.length <= 0) {
    return false;
  }
  addOptActive($event);
  clearDivListener();
  const redo = data.redoStack.pop();
  const zoom = redo["zoom"] || data.canvas.getZoom();
  if (redo == undefined) {
    return;
  }
  addUndoStack();
  data.canvas.loadFromJSON(redo, data.canvas.renderAll.bind(data.canvas));
  data.canvas.renderAll();
  const objects = redo.objects;
  let image: any = null;
  if (objects != null && objects.length > 0) {
    for (let i = 0; i < objects.length; i++) {
      const type = objects[i].type;
      if (type == "image") {
        image = objects[i];
        data.image = image;
        break;
      }
    }
  }
  if (image != null) {
    const angle = redo["angle"] || Math.trunc(image.angle);
    let orignalWidth = image.width;
    let orignalHeight = image.height;
    const oldEven = (angle / 90) % 2;
    if (oldEven != 0 && angle % 90 == 0) {
      orignalWidth = data.image.height;
      orignalHeight = data.image.width;
    }
    data.canvas.setDimensions({
      width: orignalWidth * zoom,
      height: orignalHeight * zoom
    });
    data.canvas.setZoom(zoom);
  }
  data.canvas.renderAll();
};
// 分割之前预处理 水平|垂直
const beforeSplitImage = ($event: any, isHorizontal: boolean) => {
  if (data.selectImageObj == null || data.selectImageObj.image == null || data.selectImageObj.image == undefined) {
    eleMessage("请选择要切分的文件", "warning");
    return;
  }
  clearDivListener();
  addOptActive($event);
  let fontSize = 18;
  const zoom = data.canvas.getZoom();
  fontSize = fontSize / zoom;
  data.canvas.on("mouse:down", function (ev: any) {
    const pointer = data.canvas.getPointer(ev);
    if (data.assistLine != null && data.assistLine != undefined) {
      data.canvas.remove(data.assistLine);
    }
    if (data.assistText != null && data.assistText != undefined) {
      data.canvas.remove(data.assistText);
    }
    if (isHorizontal) {
      data.assistLine = new fabric.Line([pointer.x, 0, pointer.x, data.image.height], {
        fill: "red",
        stroke: "red", //笔触颜色
        strokeWidth: 2, //笔触宽度
        selectable: false
      });
      data.assistText = new fabric.IText("双击进行切分", {
        left: pointer.x + 10,
        top: pointer.y,
        fill: "#ff0000",
        fontSize: fontSize,
        selectable: false
      });
      data.canvas.add(data.assistText);
      data.canvas.add(data.assistLine);
    } else {
      data.assistLine = new fabric.Line([0, pointer.y, data.image.width, pointer.y], {
        fill: "red",
        stroke: "red", //笔触颜色
        strokeWidth: 2, //笔触宽度
        selectable: false
      });
      data.canvas.add(data.assistLine);
      data.assistText = new fabric.IText("双击进行切分", {
        left: pointer.x + 10,
        top: pointer.y + 10,
        fill: "#ff0000",
        fontSize: fontSize,
        selectable: false
      });
      data.canvas.add(data.assistText);
    }
    data.canvas.renderAll();
    data.canvas.on("mouse:move", function (event: any) {
      data.canvas.off("mouse:down");
      const movepointer = data.canvas.getPointer(event);
      data.canvas.remove(data.assistLine);
      data.canvas.remove(data.assistText);
      data.canvas.renderAll();
      if (isHorizontal) {
        data.assistLine = new fabric.Line([movepointer.x, 0, movepointer.x, data.image.height], {
          fill: "red",
          stroke: "red", //笔触颜色
          strokeWidth: 2, //笔触宽度
          selectable: false
        });
        data.assistText = new fabric.IText("双击进行切分", {
          left: movepointer.x + 10,
          top: movepointer.y,
          fill: "#ff0000",
          fontSize: fontSize,
          selectable: false
        });
        data.canvas.add(data.assistText);
        data.canvas.add(data.assistLine);
      } else {
        data.assistLine = new fabric.Line([0, movepointer.y, data.image.width, movepointer.y], {
          fill: "red",
          stroke: "red", //笔触颜色
          strokeWidth: 2, //笔触宽度
          selectable: false
        });
        data.assistText = new fabric.IText("双击进行切分", {
          left: movepointer.x + 10,
          top: movepointer.y + 10,
          fill: "#ff0000",
          fontSize: fontSize,
          selectable: false
        });
        data.canvas.add(data.assistText);
        data.canvas.add(data.assistLine);
        data.canvas.renderAll();
      }
    });
    data.canvas.off("mouse:dblclick");
    data.canvas.on("mouse:dblclick", function (ev: any) {
      proxy.$confirm("文件拆分后不可撤销, 是否继续?", "拆分", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        callback: function (value: string) {
          if (value == "confirm") {
            clearDivListener();
            const loading = eleLoadding();
            data.WebScan.split(
              data.selectImageObj.image.imageName,
              isHorizontal,
              data.assistLine.x1,
              data.assistLine.y1,
              data.assistLine.x2,
              data.assistLine.y2,
              function (result: any) {
                loading.close();
                if (result.code == 200) {
                  eleMessage("切分成功", "success");
                  data.selectImageObj.image.src = result.data.oneSrc;
                  getAllImages();
                } else {
                  eleMessage(result.msg, "warning");
                }
              }
            );
          } else {
            data.canvas.remove(data.assistLine);
            data.canvas.remove(data.assistText);
            data.canvas.renderAll();
          }
        }
      });
      // that.splitImage(isHorizontal);
    });
  });
};
// 保存图像
const save = () => {
  if (data.imageName == null || data.imageName == "") {
    eleMessage("请选择图像", "warning");
    // this.$message.warning("请选择图像");
    return;
  }
  clearDivListener();
  let zoom = data.canvas.getZoom();
  zoom = 1 / zoom;
  const dataUrl = data.canvas.toDataURL({
    format: "jpeg",
    multiplier: zoom,
    quality: 1
  });
  const loading = eleLoadding();
  data.WebScan.saveImage(data.imageName, dataUrl, function (result: any) {
    loading.close();
    if (result.code == 200) {
      eleMessage("保存成功", "success");
      data.undoStack.length = 0;
      data.redoStack.length = 0;
      //获取选中的一张重新赋值
      const index = data.selectImageObj.index;
      const image = data.urls[index];
      image.src = dataUrl;
      data.urls.splice(index, 1, image);
      data.canvasJson = "";
      loadImage(image);
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
// 切换到上一张图像
const pre = () => {
  if (data.selectImageObj == null && data.selectImageObj == undefined) {
    eleMessage("请选择图像", "warning");
    return;
  }

  let index = data.selectImageObj.index;
  if (index <= 0) {
    eleMessage("已经是第一张了", "success");
    return;
  }
  index -= 1;
  const preObj = data.urls[index];
  selectImage(preObj, index);
};
// 切换到下一张图像
const next = () => {
  if (data.selectImageObj == null && data.selectImageObj == undefined) {
    eleMessage("请选择图像", "warning");
    return;
  }
  let index = data.selectImageObj.index;
  if (index >= data.urls.length - 1) {
    eleMessage("已经是最后一张了", "success");
    return;
  }
  index += 1;
  const nextObj = data.urls[index];
  selectImage(nextObj, index);
};
// 右键事件
const recognizeRegion = (type: string) => {
  if (data.extract.Rect == null) {
    proxy.$alert("请选择区域后识别", "警告！");
    return;
  }
  if (data.imageName == null || data.imageName == "") {
    eleMessage("请选择图像", "warning");
    // this.$message.warning("请选择图像");
    return;
  }
  data.extract.contextMenuVisible = false;
  const zoom = data.canvas.getZoom();
  const rectPoints = data.extract.Rect.getBoundingRect();
  const left = Math.ceil(rectPoints.left / zoom);
  const top = Math.ceil(rectPoints.top / zoom);
  const right = Math.ceil((rectPoints.left + rectPoints.width) / zoom);
  const bottom = Math.ceil((rectPoints.top + rectPoints.height) / zoom);
  const loading = eleLoadding();
  data.WebScan.recognizeRegionText(data.imageName, left, top, right, bottom, function (data: any) {
    loading.close();
    if (data.code != 200) {
      proxy.$alert(data.msg, "警告！");
      return;
    }
    if (data.extract.doc[type] != null && data.extract.doc[type] != undefined) {
      data.extract.doc[type] = data.data;
    } else {
      data.extract.doc[type] = data.data;
    }
  });
};
// 滑块旋转图像
const sliderRotateChange = (value: any) => {
  const oldRotate = Math.trunc(data.image.angle);
  const rotate = value - oldRotate;
  addUndoStack();
  rotateAngle(rotate);
};
const hideExtract = () => {
  $("#extract_pane").css("display", "none");
  $("#next_image").css("right", "15px");
  clearDivListener();
  data.extract.contextMenuTarget = null;
  data.canvas.remove(data.extract.Rect);
  //解除右键绑定
  contextMenu.value.unbindEvents();
  contextMenu.value.binded = false;
};
const resetForm = () => {
  doc.value.resetFields();
};
//上传OFD及提取内容
const uploadExtract = () => {
  if (data.extract.uploadUrl == "" || data.extract.uploadUrl == null) {
    proxy.$alert("请输入上传地址", "警告！");
    return;
  }
  const loading = eleLoadding("生成OFD");
  data.WebScan.majorOFD(
    true,
    true,
    function (result: any) {
      loading.close();
      if (result.code == 200) {
        data.isProcess = true;
        data.process = 0;
        //var ofdData = result.data;
        //that.uploadOfd(ofdData);
      } else {
        eleMessage(result.msg, "warning");
      }
    },
    majorOFDProcessCallback
  );
};
const majorOFDProcessCallback = (result: any) => {
  if (result.code != 200) {
    eleMessage(result.msg, "warning");
    data.isProcess = false;
    data.process = 0;
    return;
  }
  const resultData = result.data;
  let count = resultData.majored;
  if (count == undefined) {
    count = 0;
  }
  const total = resultData.total;
  if (count >= total) {
    const ofdData = resultData.data;
    if (ofdData != undefined && ofdData != null) {
      data.isProcess = false;
      uploadOfd(ofdData);
    }
  } else {
    data.process = parseInt(((count / total) * 100).toString());
  }
};
const uploadOfd = (ofdData: any) => {
  const loading = eleLoadding("上传OFD...");
  const query = window.location.search.substring(1);
  $.ajax({
    url: data.extract.uploadUrl + "?timstamp=" + new Date().getTime() + "&" + query,
    type: "post",
    data: {
      json: JSON.stringify(data.extract.doc),
      file: ofdData,
      userId: data.form.userId
    },
    success: function (result: any) {
      loading.close();
      if (result.code == 200) {
        eleMessage("上传成功", "success");
        if (data.extract.uploadUrl != undefined && data.extract.uploadUrl != "") {
          localStorage.setItem("extract-upload-url", data.extract.uploadUrl);
        }
        data.extract.isBeforeUpload = false;
      } else {
        proxy.$alert(result.msg, "警告！");
      }
    },
    error: function () {
      loading.close();
      proxy.$alert("网络错误", "警告！");
    }
  });
};
const beforeUpload = () => {
  data.WebScan.getSystemValue("uploadUrl", function (result: any) {
    if (result.code != 200) {
      return;
    } else {
      data.extract.uploadUrl = result.data;
    }
  });
  data.extract.isBeforeUpload = true;
};
const saveExtractOfd = () => {
  const loading = eleLoadding("生成Ofd...");
  let pdfName =
    data.extract.doc["sign_authority"] +
    "_" +
    data.extract.doc["title"] +
    "_" +
    data.extract.doc["issue_num"] +
    "_" +
    data.extract.doc["urgency"] +
    ".ofd";
  pdfName = pdfName.replace(RegExp("undefined", "g"), "");
  data.WebScan.writeOfd(
    pdfName,
    function (result: any) {
      loading.close();
      if (result.code == 200) {
        data.isProcess = true;
        data.process = 0;
      } else {
        eleMessage(result.msg, "warning");
      }
    },
    saveOfdCallback()
  );
};
const saveOfdCallback = (result?: any) => {
  if (result.code != 200) {
    eleMessage(result.msg, "warning");
    data.isProcess = false;
    data.process = 0;
    return;
  }
  const resultData = result.data;
  let count = resultData.majored;
  if (count == undefined) {
    count = 0;
  }
  const total = resultData.total;
  if (count >= total) {
    const ofdData = resultData.data;
    if (ofdData != undefined && ofdData != null) {
      data.isProcess = false;
      eleMessage("保存成功", "success");
    }
  } else {
    data.process = parseInt(((count / total) * 100).toString());
  }
};
// 本地上传图片
const localUpload = () => {
  fileRef.value.click();
};
const fileSelected = (event: any) => {
  const fileArr = event.target.files;
  for (let i = 0; i < fileArr.length; i++) {
    const reader = new FileReader();
    reader.onload = (event2: any) => {
      const result = {
        image: event2.target.result,
        imageName: fileArr[i].name
      };
      addImage(result);
    };
    reader.readAsDataURL(fileArr[i]);
  }
};
onMounted(() => {
  const width = $("#canvas-container").width();
  const height = $("#canvas-container").height();
  const canvas = new fabric.Canvas("imageCanvas", {
    allowTouchScrolling: true,
    centeredRotation: true,
    centeredScaling: true,
    defaultCursor: "default",
    hoverCursor: "default",
    backgroundColor: "#ffffff",
    backgroundVpt: true,
    width: width,
    height: height
  });
  data.canvas = canvas;
  addDbClick();
  data.WebScan = new WebScan({
    url: "http://127.0.0.1:18989/WebScan",
    wsUrl: "http://127.0.0.1:28989/",
    licence: data.form.scanSystem.licence
  });
  getSystem();
  init();
  data.form.userId = getQueryVariable("id");
});
// 获取电脑系统
const getSystem = () => {
  const isWin = navigator.platform == "Win32" || navigator.platform == "Windows";
  data.form.isWindow = isWin;
};
/**
 * 获物理路径odels
 * @param {Object} parentPath
 */
const getFileExplore = (parentPath: string) => {
  const loading = eleLoadding();
  data.WebScan.getFileExplore(parentPath, function (result: any) {
    loading.close();
    if (result.code == 200) {
      return result.data;
    } else {
      return "";
    }
  });
};
// 加载上传地址
const loadUploadUrl = () => {
  if (data.permissions.indexOf("ocr-extract-uploadOfd") >= 0) {
    data.WebScan.getSystemValue("uploadUrl", function (result: any) {
      if (result.code == 200) {
        data.extract.uploadUrl = result.data;
      }
    });
  }
};
// 加载模板列表
const loadModels = () => {
  const loading = eleLoadding("加载模板列表");
  data.WebScan.loadModels(function (result: any) {
    loading.close();
    if (result.code == 200) {
      let model = {
        id: null,
        name: "无"
      };
      data.modelList = result.data;
      if (data.modelList != null && data.modelList.length > 0) {
        data.modelList.unshift(model);
      }
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
// 监听键盘事件
const handleKeyDown = (event?: any) => {
  const key = event.keyCode ? event.keyCode : event.which;
  //监听ctrl+A全选文档
  if (key == 65 && event.ctrlKey) {
    if (data.urls != null && data.urls != undefined && data.urls.length > 0) {
      for (let i = 0; i < data.urls.length; i++) {
        const indexof = data.selectManyImages.indexOf(i);
        if (indexof < 0) {
          data.selectManyImages.push(i);
        }
        // this.selectManyImages.push(i);
      }
    }
    event.returnValue = false;
  }
  if (key == 37) {
  }
  if (key == 39) {
  }
};
document.addEventListener("keydown", handleKeyDown);
// 添加双击监听事件
const addDbClick = () => {
  data.canvas.on("mouse:dblclick", function () {
    if (data.canvas.getZoom() == 1) {
      ajustDimensions();
    } else {
      realDimensions();
    }
  });
};
// 加载动画
const eleLoadding = (text?: string) => {
  if (text == "" || text == undefined) {
    text = "Loading...";
  }
  return proxy.$loading({
    lock: true,
    text: text,
    spinner: "el-icon-loading",
    target: "#container",
    background: "rgba(0,0,0,0.7)"
  });
};
// 关闭当前类的加载动画
const eleUnloadding = () => {
  data.loading.close();
};
// 弹出提示框
const eleMessage = (msg: string, sign: any) => {
  if (sign == "warning" || sign == "error") {
    proxy.$alert(msg, "警告！");
    return;
  }
  proxy.$message({
    message: msg,
    type: sign,
    duration: 2000
  });
};
// 获取查询变量
const getQueryVariable = (variable: string): string => {
  const query = window.location.search.substring(1);
  const vars = query.split("&");
  for (let i = 0; i < vars.length; i++) {
    const pair = vars[i].split("=");
    if (pair[0] == variable) {
      return pair[1];
    }
  }
  return "";
};
// 获取当前系统的日志级别
const getLevel = () => {
  const loading = eleLoadding();
  data.WebScan.getLogLevel(function (result: any) {
    loading.close();
    if (result.code == 200) {
      data.logLevel = result.data;
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
// 初始化方法
const init = () => {
  const pid = sessionStorage.getItem("webscan_pid");
  const loading = eleLoadding();
  data.WebScan.licence = data.form.scanSystem.licence;
  data.WebScan.initSef(pid, function (result: any) {
    loading.close();
    if (result.code != 200) {
      //检查WebScan是否运行
      if (data.form.isWindow) {
        const protocolCheck = new (ProtocolCheck as any)();
        protocolCheck("WebScan:1", function () {
          window.confirm("请安装WebScan后使用!");
        });
      } else {
        eleMessage(result.msg, "warning");
      }
      return;
    }
    if (pid != null && pid != "" && pid != undefined) {
      data.pid = pid;
      sessionStorage.setItem("webscan_pid", data.pid);
      data.WebScan.setClientId(pid);
      //获取上次的扫描结果
    } else {
      data.pid = data.WebScan.getClientId();
      sessionStorage.setItem("webscan_pid", data.pid);
    }
    getAllImages();
    getUploadParam();
    data.WebScan.getPermission(function (result: any) {
      if (result.code == 200) {
        const auth = result.data;
        data.permissions = auth.permissions;
        loadUploadUrl();
      }
    });
    getLevel();
    // //加载模板
    loadModels();
  });
};
// 获取保存的参数
const getUploadParam = () => {
  // let that = this;
  data.WebScan.getParams(function (result: any) {
    if (result.code != 200) {
      eleMessage(result.msg, "warning");
      return;
    } else {
      if (result.data != null) {
        data.form = result.data;
        dealParams(result);
        data.isWindows = result.data.isWindow;
        if (data.form.scanSystem.licence != "" && data.form.scanSystem.licence != undefined) {
          getDevices();
        } else {
          data.preLicenceDialog = true;
        }
      }
    }
  });
};
// 处理参数数组中的内容对应在界面上显示
const dealParams = (result: any) => {
  if (data.devices == null || data.devices.length < 0) {
    data.form.device = "";
  }
  if (
    data.form != null &&
    data.form != undefined &&
    data.form.scanSystem != null &&
    data.form.scanSystem != undefined &&
    data.form.scanSystem.imagePath != null &&
    data.form.scanSystem.imagePath != undefined &&
    data.form.scanSystem.imagePath != ""
  ) {
    data.treePlaceHolder = data.form.scanSystem.imagePath;
  }
  if (result.data.params != null) {
    if (result.data.isWindow) {
      data.split = "0";
      data.autoRotate = "0";
    } else {
      data.split = "None";
      data.autoRotate = "0";
    }
    for (let i = 0; i < result.data.params.length; i++) {
      let param = result.data.params[i];
      if (result.data.isWindow) {
        if (param.code == "9266") {
          data.split = param.value;
        }
        if (param.code == "1152") {
          data.autoRotate = param.value;
        }
        if (param.code == "1136") {
          data.flipSideRotationWindows = param.value;
        }
      } else {
        if (param.code == "split-image") {
          data.splitLinux = param.value;
        }
        if (param.code == "rotate") {
          data.autoRotateLinux = param.value;
        }
        if (param.code == "flip-side-rotation") {
          data.flipSideRotationLinux = param.value;
        }
      }
    }
  }
  if (result.data.sort == undefined) {
    result.data.sort = null;
  }
  if (result.data.sort != null && result.data.sort != "") {
    if (result.data.isWindow) {
      data.split = "1";
      data.autoRotate = "0";
    } else {
      data.split = "Horizontal";
      data.autoRotate = "None";
    }
  }
  if (data.form.cheek == null || data.form.cheek == undefined) {
    data.form.cheek = 0;
  }
  if (result.data.isWindow) {
    data.minCheek = 0;
    data.maxCheek = 5;
  }
  if (data.form.netWorkScanParam == null) {
    data.form.netWorkScanParam = networkScanParam;
  }
};
// 获取所有的图像
const getAllImages = () => {
  const loading = eleLoadding();
  data.WebScan.getAllImages(function (result: any) {
    loading.close();
    if (result.code == 200) {
      if (result.data != null && result.data.length > 0) {
        data.urls = result.data;
        selectImage(data.urls[0], 0);
      }
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
// 为左边列表中单选图像添加红框，其他图像去除红框
const addOptActive = (e: any) => {
  if (e == null || e == undefined) {
    return;
  }
  $(e.currentTarget).addClass("active");
  $(e.currentTarget).siblings().removeClass("active");
};
// 选择图片
const selectImage = (image: { src: string; imageName: string }, index: number) => {
  checkImageModify(image, index);
  data.selectManyImages = [];
  data.selectManyImages.push(index);
};
// 多选图像
const selectManyImage = (image: { src: string; imageName: string }, index: number) => {
  const indexof = data.selectManyImages.indexOf(index);
  if (indexof >= 0) {
    const nextIndex = indexof + 1;
    if (nextIndex < data.selectManyImages.length) {
      const index = data.selectManyImages[nextIndex];
      checkImageModify(data.urls[index], index);
    } else {
      const preIndex = indexof - 1;
      if (preIndex >= 0) {
        const index = data.selectManyImages[preIndex];
        checkImageModify(data.urls[index], index);
      } else {
        checkImageModify(null as any, 0);
        $(".canvas-container").css("border", "none");
      }
    }
    data.selectManyImages.splice(indexof, 1);
  } else {
    data.selectManyImages.push(index);
    checkImageModify(data.urls[index], index);
  }
};
// 检查更换展示图像时是否需要更新
const checkImageModify = (image: { src?: string; imageName?: string }, index: number) => {
  if (image == null) {
    return;
  }
  if (data.canvasJson != null && data.canvasJson != "") {
    const dataUrl = data.canvas.toDatalessJSON();
    //发生更改，做更新提醒
    if (JSON.stringify(dataUrl) != JSON.stringify(data.canvasJson)) {
      proxy.$confirm("文件发生更改是否需要保存?", "保存", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        callback: function (value: string) {
          if (value == "confirm") {
            clearDivListener();
            let zoom = data.canvas.getZoom();
            zoom = 1 / zoom;
            const dataUrl = data.canvas.toDataURL({
              format: "jpeg",
              multiplier: zoom,
              quality: 1
            });
            const loading = eleLoadding();
            data.WebScan.saveImage(data.imageName, dataUrl, function (result: { code: number; msg: any }) {
              loading.close();
              if (result.code == 200) {
                eleMessage("保存成功", "success");
                data.undoStack.length = 0;
                data.redoStack.length = 0;
                //获取选中的一张重新赋值
                data.canvasJson = "";
                //更改图像列表中的base64
                const pre_index = data.selectImageObj.index;
                data.urls[pre_index].src = dataUrl;
                data.selectImageObj = {
                  image: data.urls[index],
                  index: index
                };
                loadImage(data.urls[index]);
              } else {
                eleMessage(result.msg, "warning");
              }
              data.selectImageObj = {
                image: data.urls[index],
                index: index
              };
              loadImage(data.urls[index]);
            });
          } else {
            data.selectImageObj = {
              image: data.urls[index],
              index: index
            };
            loadImage(data.urls[index]);
          }
        }
      });
    } else {
      data.selectImageObj = {
        image: data.urls[index],
        index: index
      };
      loadImage(data.urls[index]);
    }
  } else {
    data.selectImageObj = {
      image: data.urls[index],
      index: index
    };
    loadImage(data.urls[index]);
  }
};
// 调整图像位置
const onEndDrag = (evt: any) => {
  const oldIndex = evt.oldIndex;
  const newIndex = evt.newIndex;
  data.WebScan.changeIndex(oldIndex, newIndex, function (result: any) {
    if (result.code != 200) {
      proxy.$message.warning(result.msg);
      return;
    }
    eleMessage("调整成功", "success");
  });
};
// 清除canvas上所有的监听
const clearDivListener = () => {
  $("#canvas-container").unbind("mouseup");
  $("#canvas-container").unbind("mousedown");
  data.canvas.defaultCursor = "default";
  data.canvas.hoverCursor = "default";
  data.canvas.off("mouse:down");
  data.canvas.off("mouse:up");
  data.canvas.off("mouse:move");
  data.canvas.off("mouse:dblclick");
  data.rectificationDialog = false;
  if (data.assistLine != null && data.assistLine != undefined) {
    data.canvas.remove(data.assistLine);
  }
  if (data.assistText != null && data.assistText != undefined) {
    data.canvas.remove(data.assistText);
  }
  addDbClick();
};
// 加载大图
const loadImage = (imageObj: { src: any; imageName: string } | null | undefined) => {
  clearDivListener();
  data.canvas.clear();
  data.canvas.setZoom(1);
  // this.totalAngle=0;
  data.canvas.discardActiveObject();
  if (imageObj == null || imageObj == undefined) {
    return;
  }
  const src = imageObj.src;
  new fabric.Image.fromURL(
    src,
    function (image: { width: number; height: number; angle: number }) {
      data.image = image;
      data.imageName = imageObj.imageName;
      data.canvas.add(image);
      data.canvas.renderAll();
      ajustDimensions();
      const dataUrl = data.canvas.toDatalessJSON();
      data.canvasJson = dataUrl;
    },
    {
      selectable: false
    }
  );
  $(".canvas-container").css("border", "2px solid #e1e1e1");
};
// 图像大图自适应显示
const ajustDimensions = ($event?: any) => {
  addOptActive($event);
  clearDivListener();
  if (data.image == null || data.image == undefined) {
    return;
  }
  let orignalWidth = data.image.width;
  let orignalHeight = data.image.height;
  const angle = Math.trunc(data.image.angle);
  const oldEven = (angle / 90) % 2;
  if (oldEven != 0 && angle % 90 == 0) {
    orignalWidth = data.image.height;
    orignalHeight = data.image.width;
  }
  const width = $("#canvas-container").width() - 4;
  const height = $("#canvas-container").height() - 4;
  const zoom = Math.min(width / orignalWidth, height / orignalHeight);

  //图像压缩
  if (width > data.image.width && height > orignalHeight) {
    orignalWidth = data.image.width;
    orignalHeight = data.image.height;
  } else if (zoom < 1) {
    orignalWidth = orignalWidth * zoom;
    orignalHeight = orignalHeight * zoom;
    data.canvas.setZoom(zoom);
  } else {
    data.canvas.setZoom(zoom);
  }
  data.canvas.setDimensions({
    width: orignalWidth,
    height: orignalHeight
  });
  data.canvas.renderAll.bind(data.canvas);
  clearDivListener();
};
// 图像大图真实大小显示
const realDimensions = ($event?: any) => {
  addOptActive($event);
  clearDivListener();
  if (data.image == null || data.image == undefined) {
    return;
  }
  //判断是否需要横放
  const angle = Math.trunc(data.image.angle);
  const oldEven = (angle / 90) % 2;
  if (oldEven != 0 && angle % 90 == 0) {
    data.canvas.setDimensions({
      width: data.image.height,
      height: data.image.width
    });
  } else {
    data.canvas.setDimensions({
      width: data.image.width,
      height: data.image.height
    });
  }
  data.canvas.setZoom(1);
  data.canvas.renderAll.bind(data.canvas);
};
// 导出OFD
const exportOfd = () => {
  if (data.urls == null || data.urls.length <= 0) {
    eleMessage("该批次不包含图像", "warning");
    return;
  }
  const loading = eleLoadding();
  data.WebScan.majorOFD(
    true,
    data.isDoubleOfd,
    function (result: any) {
      loading.close();
      if (result.code == 200) {
        if (data.isDoubleOfd == 1 || data.isDoubleOfd == true) {
          data.isProcess = true;
          data.process = 0;
          data.isSelectDoubleOfd = false;
        } else {
          const ofdData = result.data;
          if (ofdData != undefined && ofdData != null) {
            const blob = dataURLtoBlob(ofdData);
            const ofdName = data.pid + ".ofd";
            downloadFile(blob, ofdName);
            data.isProcess = false;
            data.process = 0;
            data.isSelectDoubleOfd = false;
          }
        }
      } else {
        eleMessage(result.msg, "warning");
      }
    },
    compressProcessCallback
  );
};
// 导出PDF
const exportPdf = (pdfName?: any) => {
  if (data.urls == null || data.urls.length <= 0) {
    eleMessage("该批次不包含图像", "warning");
    return;
  }
  const loading = eleLoadding();
  if (pdfName == "" || pdfName == null) {
    pdfName = data.pid + ".pdf";
  }
  data.WebScan.majorPDF(data.isDoublePdf, function (result: any) {
    loading.close();
    if (result.code == 200) {
      const resultData = result.data;
      if (resultData != null && resultData != undefined) {
        const blob = dataURLtoBlob(resultData);
        downloadFile(blob, pdfName);
      }
    } else {
      proxy.$message.warning(result.msg);
    }
  });
  loading.close();
};
// 下载ZIP
const downLoadZip = () => {
  const loading = eleLoadding();
  data.WebScan.majorZip(function (result: any) {
    loading.close();
    if (result.code == 200) {
      const resultData = result.data;
      if (resultData != null && resultData != undefined) {
        const blob = dataURLtoBlob(resultData);
        const ofdName = data.pid + ".zip";
        downloadFile(blob, ofdName);
      }
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
const downloadDocx = () => {
  const loading = eleLoadding();
  data.WebScan.majorDocx(function (result: any) {
    loading.close();
    if (result.code == 200) {
      data.isProcess = true;
      data.process = 0;
    } else {
      eleMessage(result.msg, "warning");
    }
  }, compressProcessCallback);
};
// 下载文件
const downloadFile = (blob: Blob | MediaSource, filename: string) => {
  const file = blobToFile(blob, filename);
  const aLink = document.createElement("a");
  document.body.appendChild(aLink);
  const evt = document.createEvent("HTMLEvents");
  evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错  事件类型，是否冒泡，是否阻止浏览器的默认行为
  aLink.download = filename;
  aLink.href = URL.createObjectURL(blob);
  aLink.click();
  document.body.removeChild(aLink);
};
// 将base64转换为blob
const dataURLtoBlob = (dataurl: string) => {
  const bstr = atob(dataurl);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr]);
};
// 将blob转换为file
const blobToFile = (theBlob: any, fileName: string) => {
  theBlob.lastModifiedDate = new Date();
  theBlob.name = fileName;
  return theBlob;
};
// 异步导出进度回调函数
const compressProcessCallback = (result: any) => {
  if (result.code != 200) {
    eleMessage(result.msg, "warning");
    data.isProcess = false;
    data.process = 0;
    data.isSelectDoubleOfd = false;
    return;
  }
  const resultData = result.data;
  let count = resultData.majored;
  if (count == undefined) {
    count = 0;
  }
  const total = resultData.total;
  if (count >= total) {
    const ofdData = resultData.data;
    if (ofdData != undefined && ofdData != null) {
      const blob = dataURLtoBlob(ofdData);
      const type = resultData.type;
      const ofdName = data.pid + "." + type;
      downloadFile(blob, ofdName);
      data.isProcess = false;
      data.process = 0;
      data.isSelectDoubleOfd = false;
    }
  } else {
    data.process = parseInt(((count / total) * 100).toString());
  }
};
// 扫描回调函数
const scanCallBack = (result: any) => {
  eleUnloadding();
  let code = result.code;
  if (code == 201) {
    if (data.permissions.indexOf("oprate-disable") >= 0) {
      data.isDisableOpt = true;
    }
    console.log(result);

    addImage(result);
  }
  if (code == 203) {
    data.isDisableOpt = false;
    data.isInsertScan = false;
    data.isCoverScan = false;
    data.oprationImageObj = {};
    //根据后台参数判断是否需要骑订排序
    orderByRiding();
  }
  if (result.code == 500) {
    data.isDisableOpt = false;
    eleMessage(result.msg, "warning");
  }
};
// 对左侧图片预览进行图片添加
const addImage = (result: any) => {
  const image = {
    src: result.image,
    imageName: result.imageName
  };
  if (data.isInsertScan) {
    //找到文件位置，插入元素
    if (data.oprationImageObj == null || data.oprationImageObj.index < 0 || data.oprationImageObj.index == undefined) {
      data.urls.push(image);
    } else {
      const index = data.oprationImageObj.index;
      data.urls.splice(index, 0, image);
      data.oprationImageObj.index += 1;
    }
  } else if (data.isCoverScan) {
    if (data.oprationImageObj == null || data.oprationImageObj.index < 0 || data.oprationImageObj.index == undefined) {
      data.urls.push(image);
    } else {
      const index = data.oprationImageObj.index;
      //替换当前元素
      data.urls.splice(index, 1, image);
      //找下一个元素
      if (index == data.urls.length - 1) {
        data.oprationImageObj = {};
      } else {
        data.oprationImageObj = {
          image: data.urls[index + 1],
          index: index + 1
        };
      }
    }
  } else if (data.isPageCover) {
    let isFirst = result.first;
    if (isFirst != null && isFirst) {
      data.urls.unshift(image);
    } else {
      data.urls.push(image);
    }
  } else {
    // this.urls.unshift(image);
    data.urls.push(image);
  }
  if (data.permissions.indexOf("oprate-disable") >= 0) {
    selectImage(data.urls[data.urls.length - 1], data.urls.length - 1);
  }
};
const orderByRiding = () => {
  const loading = eleLoadding("骑订排序中");
  data.WebScan.getParams(function (result: any) {
    loading.close();
    if (result.code == 200) {
      const params = result.data;
      const sortType = params.sort;
      if (sortType != undefined && sortType != null) {
        data.sortMode = sortType;
        sortImageHttp();
      } else {
        if (data.selectImageObj == null || data.selectImageObj.index == -1) {
          if (data.urls != null && data.urls.length > 0) {
            selectImage(data.urls[0], 0);
          }
        }
      }
    } else {
      eleMessage(result.msg, "warning");
    }
  });
};
</script>

<style scoped>
@import "./css/scan.scss";
.el-loading-mask {
  z-index: 2002 !important;
}
.total {
  position: fixed;
  background-color: #eaeaea;
  bottom: 0px;
  width: 195px;
  height: 25px;
  line-height: 25px;
  padding-left: 20px;
  color: #666;
  box-sizing: border-box;
}
</style>
